Отображение одной сущности ngrx в цикле ngFor с использованием идентификаторов - PullRequest
0 голосов
/ 05 сентября 2018

Я использую ng6 с NGRX для отображения двух наборов данных в представлении. Первый набор данных - это полный набор данных. Второй набор данных является подмножеством первого набора данных.

Мне нужно использовать цикл ngFor во втором наборе данных, который обеспечивает id, а внутри цикла использовать id, чтобы отобразить одну сущность из первого набора данных.

component.ts

export class ViewComponent implements OnInit {
  datasetOne$: Observable<data[]>;
  datasetTwo$: Observable<data[]>;

  constructor(private store: Store<fromStore.DatasetState>) {}

  ngOnInit() {
    this.store.dispatch(new fromStore.LoadDatasetOne());
    this.store.dispatch(new fromStore.LoadDatasetTwo());
    this.datasetOne$ = this.store.select(fromStore.getDatasetOne);
    this.datasetTwo$ = this.store.select(fromStore.getDatasetTwo);
  }

}

component.html

<ul>
    <li *ngFor="let data of (datasetOne$ | async)">{{ data.name }}</li>  
</ul>

Subset:

<ul>
    <li *ngFor="let subData of (datasetTwo$ | async)">{{ subData.id }}</li>  
</ul>

На этом экране правильно отображаются оба подмножества, имена и идентификаторы (цифры)

subData.id соответствует имени в datasetOne, я хочу отобразить имя вместо id

Это как-то так для вида:

<li *ngFor="let subData of (datasetTwo$ | async)">{{ getNameById(subData.id) }}</li>

но мне не удалось написать метод, который может получить одну сущность из datasetOne$

Ответы [ 2 ]

0 голосов
/ 05 сентября 2018

Поскольку вы уже используете селекторы, я бы предложил создать новый селектор на основе текущих двух.

const combinedSelector = createSelect(datasetOne, datasetTwo,
  (one, two) => ...
)

Если это невозможно, вы также можете сделать следующее, как указано в NgRx: параметризованные селекторы

export const selectCustomer = createSelector(
  selectCustomers, 
  customers => (id: string) => customers[id]
);

// tip: it’s also possible to memoize the function if needed
export const selectCustomer = createSelector(
  selectCustomers, 
  customers => memoize((id: string) => customers[id])
);

// and in the HTML
{{ (customers | async)(id).name }}
0 голосов
/ 05 сентября 2018

У вас в основном два потока, и вы хотите создать новый поток, используя значения из обоих. Вам нужно использовать zip

Документ: http://reactivex.io/documentation/operators/zip.html

Синтаксис выглядит примерно так:

Observable.zip ( source 1, source 2, function )

Пример:

const dataNames = Rx.Observable.of(['name1','name2','name3']);
const dataId = Rx.Observable.of([0,2,1]);

Rx.Observable.zip(
   dataId,
   dataNames,
   (arr1,arr2)=> arr1.map(id=> arr2[id])  // change this to your requirement
).subscribe(console.log);
<script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>
...