Отображение одной сущности ngrx в цикле ngFor с использованием идентификаторов
Я использую 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 ответа
Поскольку вы уже используете селекторы, я бы предложил создать новый селектор на основе текущих двух.
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 }}
В основном у вас есть два потока, и вы хотите создать новый поток, используя значения из обоих. Вам нужно использовать 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>