J'ai une table que je filtrant sur la base d'un champ entré par l'utilisateur, et la source de ce tableau est une fabriquée observable à partir d'un comportement. Voici la configuration:
<input type="text" [(ngModel)]="state" />
3 Réponses :
Vous pouvez utiliser la fonction rxjs combineLatest et avoir une trace observable besoin de recalculer:
<input type="text" (ngModelChange)="stateSubject.next($event)" [(ngModel)]="state" />
Et puis sur votre entrée:
private subject$ = new BehaviorSubject([]) public state = 'Open'; public stateSubject = new BehaviorSubject(this.state); public workOrders$ = combineLatest( this.subjects$, this.stateSubject, (orders, state) => { return orders.filter(f => f.State == state) } );
Vous avez mentionné que state
provenait d'un champ de saisie, ce qui signifie (en supposant que le FormsModule
est importé, qu'il devrait prendre en compte le ngModel
) nous pouvons obtenir cette valeur en tant qu'observable.
Vous pouvez utiliser switchMap
pour vous abonner à un observable, mapper ses émissions sur un deuxième observable et faire émettre les valeurs observables résultantes du deuxième observable jusqu'au premier Observable émet à nouveau (vous basculez vers le nouvel Observable).
Vous pouvez obtenir l'Observable des changements de valeur à partir de votre contrôle de formulaire de différentes manières selon la façon dont le formulaire est mis en place, ou même simplement en utilisant une liaison (keyup)
. Sans
ngForm
déclaré dans le modèle attaché au champ, vous pouvez simplement interroger le ngModel
via la liaison de modèle:
<input type="text" [(ngModel)]="state" /> <tr *ngFor="let order of workOrders$ | async | filterState:state">
puis dans votre composant:
class Component {
@Pipe({name: 'filterState'}) export class FilterStatePipe implements PipeTransform { transform(value: YourTypeHere[], state: string) { return value.filter(s => s.State === state); } }
Vous pouvez également gérer séparément l'abonnement à partir de l'appel http et des changements de valeur d'entrée, mais ce n'est pas amusant.
Comme vous pouvez le voir, ce qui précède devient un peu compliqué; nous avons besoin de withLatestFrom
pour conserver la valeur de l'appel http, qui, je suppose, est statique une fois reçu. Puisque vous utilisez le tube async
dans le balisage pour vous abonner et appeler l'Observable, il peut être préférable de filtrer simplement ce résultat avec un autre tube!
@ViewChild('value') value: NgModel; //filled with a http call to a webservice private subject = new BehaviorSubject([]) public state = 'Open'; // This remains as a component property, but we don't need it for the Observable stream as we'll get the value changes Observable from the form control. public workOrders = this.subject.asObservable().pipe( switchMap(this.value.valueChanges), withLatestFrom(this.subject), map([inputValue, orders] => { return orders.filter(f => f.State === inputValue.value) })); }
Ensuite, déclarez-le dans votre module et utilisez-le dans votre balisage comme ceci:
<input type="text" [(ngModel)]="state" #value="ngModel"/>
async
déballe l'Observable pour vous, alors votre canal personnalisé filtrera cette valeur en fonction de la valeur de state
. Lorsque state
change, le tube doit être réexécuté.
Vous devez vous abonner aux modifications de la valeur d'entrée
Cela peut être fait soit en convertissant le formulaire (en supposant que le champ de saisie se trouve dans un formulaire) en un formulaire réactif, soit en appelant une fonction chaque fois que la valeur d'entrée change
Vous trouverez plus d'informations sur les formulaires réactifs ici
Je vais passer en revue la deuxième et la plus simple méthode:
HTMLclass Component {
//filled with a http call to a webservice
private subject$ = new BehaviorSubject([])
public state = 'Open';
public allorders
//Variable to hold all the subjects before applying any filter
this.subjects$.asObservable().subscribe( val => {
this.allorders = val
})
}
dataChanged(){
this.allorders.filter(f => f.State == this.state)
}));
}
<input type="text" (ngModelChange)="dataChanged()" [(ngModel)]="state" />
Comment l '
état
va-t-il être modifié? Est-ce un champ de saisie?Oui, désolé, c'est lié à un champ de saisie. J'ajouterai cela à la question