0
votes

Réexécuter le tube pour l'observable lorsque la condition change (Angular 7)

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" />


2 commentaires

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


3 Réponses :


1
votes

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)
    }
);


0 commentaires

0
votes

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.

Cependant ...

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é.


0 commentaires

0
votes

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: HTML

class 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" /> 


0 commentaires