#angular #ngrx
#angular #ngrx
Вопрос:
мое хранилище ngrx состоит из двух наборов данных: preferenceGroups
которые содержат группы выбранных значений предпочтений и stocks
:
существует множество preferenceGroups
, в одном из двух форматов, группа логических значений или диапазон:
"preferenceGroups": [
{
"name": "Sectors",
"type": "toggles",
"preferences": [
{
"label": "Sector 1",
"type": "boolean",
"value": true
},
{
"label": "Sector 2",
"type": "boolean",
"value": true
}
]
},
{
"name": "Exchange",
"type": "toggles",
"preferences": [
{
"label": "Exchange 1",
"type": "boolean",
"value": true
},
{
"label": "Exchange 2",
"type": "boolean",
"value": true
}
]
},
{
"name": "Price",
"type": "price-range",
"preferences": {
"label": "Price",
"type": "currency",
"value": {
"minimum": 0,
"maximum": 999
}
}
},
...
]
У меня также есть куча запасов, все с одинаковыми полями, обычно они выглядят так:
"stocks": [
{
"state": {
"accepted": false,
"rejected": false
},
"change": -5.36,
"changePercent": -0.13,
"dividend": 12.05,
"equitySummaryScore": 8,
"exchange": "Exchange 1",
"price": 97.10,
"sector": "Sector 1",
...
},
...
]
Способ работы моих фильтров заключается в том, что для каждой группы предпочтений я хотел бы рассмотреть любой запас, значение которого соответствует любому из логических фильтров, для которого установлено значение true, а в случае диапазона — любое значение, которое находится в пределах диапазона.
Я могу получить все запасы и группы предпочтений из моего хранилища ngrx в качестве наблюдаемых, используя
this.stocks = this._store.select('stocks');
this.preferenceGroups = this._store.select('preferenceGroups');
что мне нужно сделать, это сохранить отфильтрованные запасы как наблюдаемые, используя данные this.preferenceGroups
для фильтрации this.stocks
.
this.filteredStocks = [something I can't figure out]
например, единственный указанный мной запас будет совпадать, потому что он имеет "exchange": "Exchange 1"
, "sector": "Sector 1"
и "price": "97.10"
Ответ №1:
Если у вас есть две наблюдаемые, одна с запасами, другая с вашим фильтром, вам необходимо объединить оба потока. Что вам нужно, так это массив каждого запаса и ваши предпочтения, чтобы знать, можете ли вы их показать. Проверьте следующий код:
let stocks$ = Rx.Observable.of(["stock1", "stock2", "stock3"]);
let preferences$ = Rx.Observable.of(["preference", "preference2"]);
let combined$ = Rx.Observable.combineLatest(
stocks$, preferences$, (stocks, preferences) => {
// implement your filtering logic here and returned the filtered stocks
return stocks " " preferences
});
combined$.subscribe((val) => console.log(val));
При использовании combineLatest вы объединяете две наблюдаемые. Функции, которая передается методу combineLatest, будет присвоено последнее значение из stocks $ observable и последнее из preferences $ observable. Эти наблюдаемые данные поступают из вашего хранилища.
В этой функции вы можете просто реализовать логику фильтрации, как в императивном стиле.
Каждый раз, когда в хранилище добавляется новый запас, ngrx добавит новое значение в наблюдаемый запас, и функция с вашей логикой будет переоцениваться. То же самое касается нового предпочтения.
Если вы подписываетесь на ваш объединенный $ stream в вашем шаблоне, каждое добавление запаса или добавление предпочтений приведет к обновленному представлению.
Комментарии:
1. отличный ответ @KwintenP, это было именно то, что я искал.
2. Где будет жить приведенный вами пример функции? В новой службе, подобной
FilteredStockService
или какой-либо другой вычисляемой службе хранения наблюдаемых.3. По этой логике я бы либо вставил интеллектуальный компонент, чтобы создать поток, и передал его немому компоненту. Или я бы сделал это на уровне абстракции, который мне нравится называть песочницей (читайте о том, что это здесь: blog.brecht.io/A-scalable-angular2-architecture