简体   繁体   English

使用管道和地图创建角度过滤器

[英]Angular creating filter with pipe and map

I am fairly new to angular and I am trying to create a filter for a value.我对 angular 还很陌生,我正在尝试为一个值创建一个过滤器。

In my component - I have => myData$: Observable<MyInterface>在我的组件中 - 我有 => myData$: Observable<MyInterface>

and the interface is as follows界面如下

export class FoundValues {
    customerName: string;
    startDate: string;
    endDate: string;
    includes(values: string) : boolean {
      value = value.toLowerCase();
      return this.valueIncludes(this.customerName, value);
    }

    private valueIncludes(includedValue, value){
       if (value) {
         const value = value.toLowerCase().includes(includedValue);
         return result;
       } else {
          return false;
       }
    }
}
export interface MyInterface {
    found_values : Array<FoundValues>;
}

In my component ngOnInit(), I am trying to create a logic filter but not getting it as it return a type FoundValues[] and it's complaining that it's not the expected Observable return type.在我的组件 ngOnInit() 中,我试图创建一个逻辑过滤器,但没有得到它,因为它返回一个类型 FoundValues[] 并且它抱怨它不是预期的 Observable 返回类型。

export class MyComponent implements OnInit{
      myData$ = Observable<MyInterface>;
      myControl = new FormControl();

     ngOnInit(): void{
        this.filterData = 
        this.myControl.valueChanges.pipe(map(value=>this._filter(value)));
     }
     private _filter(value:string): .....{
         --- need logic here ----
     }
}

How can I create the filter so that if I type a customer name in my form it shows only the matching customer name?如何创建过滤器,以便在表单中键入客户名称时,它仅显示匹配的客户名称?

You can use the combineLatest RxJS operator for filtering through as shown in the following code snippet,您可以使用combineLatest RxJS 运算符进行过滤,如下面的代码片段所示,

export class MyComponent implements OnInit {
  myData$ = Observable < MyInterface > ;
  mySearchQuery$: Observable < any > ;
  searchString = new FormControl('');

  filterData: Observable < any >

    constructor() {
      mySearchQuery$ = this.searchString.valueChanges.startsWith('');
    }

  ngOnInit(): void {
    this.filterData = this.searchQuery$.combineLatest(this.myData$).map(([queryString, listOfCustomers]) => {
      return listOfCustomers.filter(customer => customer.name.toLowerCase().indexOf(queryString.toLowerCase()) !== -1)
    })
  }
}

The combineLatest RxJS operator takes in the observables myData$ and mySearchQuery and returns the observable filterData containing the emitted values that match the searchString . combineLatest RxJS 运算符接收可观察值myData$mySearchQuery并返回可观察值filterData其中包含与searchString匹配的发射值。

usual design in angular would be different通常的角度设计会有所不同

https://stackblitz.com/edit/angular7-rxjs-pgvqo5?file=src/app/app.component.ts https://stackblitz.com/edit/angular7-rxjs-pgvqo5?file=src/app/app.component.ts

interface Entity {
  name: string;
  //...other properties
}

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent {
  name = new FormControl('');
  data$: Observable<Array<Entity>> = of([
    { name: 'Jhon' },
    { name: 'Jane' },
    { name: 'Apple' },
    { name: 'Cherry' },
  ]);

  filtered$: Observable<Array<Entity>>;

  ngOnInit() {
    // this can be moved to a util lib/file
    const startWithPipe = pipe(
      map(
        ([query, data]: [query: string, data: Array<Entity>]): Array<Entity> =>
          data.filter((entity) =>
            query ? entity.name.toLowerCase().startsWith(query) : true
          )
      )
    );

    this.filtered$ = this.name.valueChanges.pipe(
      startWith(''),
      debounceTime<string>(300),
      withLatestFrom(this.data$),
      startWithPipe
    );
  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM