Как отфильтровать наблюдаемую переданную в угловую составляющую? - PullRequest
0 голосов
/ 18 января 2019

Я новичок в RxJs operators and Observables в целом и не был уверен, как заставить этот простой код работать.

Я создал компонент с именем 'family-list', который связан с наблюдаемой из 'PlanMember[]'. Это передается из компонента контейнера.

Внутри этого компонента я хочу иметь возможность отфильтровывать участников плана, чтобы мы пропустили участника с userType 'Owner'. Код, который у меня есть, теперь не работает, потому что 'planMembers' не определено.

Пожалуйста, помогите!

@Component({
  selector: 'pv-family-list',
  templateUrl: './family-list.component.html',
  styleUrls: ['./family-list.component.scss']
})
export class FamilyListComponent{
  @Input() planMembers: Observable<PlanMember[]>;
  @Output() remove: EventEmitter<string> = new EventEmitter<string>();

  columnsToDisplay = ['name', 'email', 'status', 'cycleEnd', 'actions'];

  constructor() { 
    this.planMembers.pipe(map( (members) =>  members.filter(m => m.userId !== 'Owner') )).subscribe();
  }
  removeUser (userId : string) {
    this.remove.emit(userId);
  }
}

EDIT: После использования ngOnit для фильтрации - Моя страница загрузит компонент, но все равно получит ошибки. Я также даже не получаю список участников, чтобы фильтровать должным образом - все еще есть все участники

Итак, у меня есть компонент Subscription.container, который содержит этот компонент списка семейства. Я получаю список членов семьи из магазина. this.familyPlanMembers$ = store.select(fromAccount.getPlanMembers); Затем я связываю своих членов плана семейства с помощью асинхронного канала: <pv-family-list (remove)="cancelMemberSubscription($event)" [planMembers]="(familyPlanMembers$ | async)" > </pv-family-list> Пока загружается список семьи, я получаю следующее: TypeError: "this.planMembers is null"

Компонент сейчас:


@Component({
  selector: 'pv-family-list',
  templateUrl: './family-list.component.html',
  styleUrls: ['./family-list.component.scss']
})
export class FamilyListComponent implements OnChanges{
  @Input() planMembers: PlanMember[];
  @Output() remove: EventEmitter<string> = new EventEmitter<string>();

  columnsToDisplay = ['name', 'email', 'status', 'cycleEnd', 'actions'];

  ngOnChanges() { 
    this.planMembers = this.planMembers.filter(m => m.userType !== 'Owner');
  }

  removeUser (userId : string) {
    this.remove.emit(userId);
  }

Ответы [ 3 ]

0 голосов
/ 18 января 2019

В constructor раз ваш @Input еще не определен.

Переместите свой код в ngOnInit:

@Component({
  selector: 'pv-family-list',
  templateUrl: './family-list.component.html',
  styleUrls: ['./family-list.component.scss']
})
export class FamilyListComponent implements OnInit{
  @Input() planMembers: Observable<PlanMember[]>;
  @Output() remove: EventEmitter<string> = new EventEmitter<string>();

  columnsToDisplay = ['name', 'email', 'status', 'cycleEnd', 'actions'];

  ngOnInit() { 
    this.planMembers.pipe(map( (members) =>  members.filter(m => m.userId !== 'Owner') )).subscribe();
  }
  removeUser (userId : string) {
    this.remove.emit(userId);
  }
}

Тогда это также зависит от того, как вы передаете этот ввод через этот компонент, и как вы извлекаете данные, в противном случае вы должны реализовать ngOnChanges вместо ngOnInit, или использовать set на @Input, или возможны многие другие подходы

0 голосов
/ 18 января 2019

Как и другие уже упомянутые ответы, Observable еще не определен в конструкторе.Конструктор должен использоваться только для DI или присваиваний imho.

Я бы предложил не , чтобы передать наблюдаемое в качестве входных данных вашим дочерним компонентам, а передать его как «просто» массив.Это сделает ваше приложение быстрее, проще в работе и проще в тестировании.Чтобы передать его как массив, используйте канал async.

<pv-family-list [planMembers]="planMembers$ | async"><pv-family-list/>
0 голосов
/ 18 января 2019

Не определено, поскольку не инициализировано. Вы должны выполнить фильтрацию в хуке ngOnInit и ngOnChanges или использовать метод set

_planMembers:  Observable<PlanMember[]>;

@Input
set planMembers(planMembers: Observable<PlanMember[]]) {
    this._planMembers = planMembers;
    this._planMembers
        .pipe(map( (members) =>  members.filter(m => m.userId !== 'Owner') 
    )).subscribe();

}

Это будет вызываться каждый раз, когда изменяется вход в planMembers.

...