好的,我会尝试解释一种设置方法,希望能以一种你和其他人都能理解的方式来表达。如果您正在存储一个对象数组,并需要通过特定的ID或键访问行,则ngrx示例应用程序显示的方法是创建一个包含您的对象的对象,它将使用(在其书籍应用程序的情况下)书籍的ID作为属性键。您可以将任何字符串设置为属性名称。因此,假设您的状态具有名为“entities”的属性,其值为一个空对象。然后,您可以在“entities”对象上创建属性来处理数组。
export interface BooksState {
entities: { [id: string]: Book };
};
让我们从书籍对象数组中的一行开始。要将此行添加到“entities”对象中,可以按照以下方式执行。
reducerState.entities[book.id] = book
以上操作将使得书籍的id成为“entities”对象上的一个属性。
如果您在控制台或调试工具中进行检查,它可能在创建后看起来像这样。
reducerState.entities.15: { id: 15, name: "To Kill a Mockingbird" }
ngrx示例应用程序使用javascript数组上的reduce运算符对完整数组进行操作,将其添加到状态中。
const newBookEntities
= newBooks.reduce(
(entities: { [id: string]: Book }, book: Book) =>
{
return Object.assign(entities, { [book.id]: book });
}, {});
然后创建特殊函数来获取此状态的部分,稍后可以将它们组合在一起以获取所需的特定行。
export function getBooksState() {
return (state$: Observable<AppState>) => state$
.select(s => s.books);
}
export function getBookEntities() {
return (state$: Observable<BooksState>) => state$
.select(s => s.entities);
};
export function getBooks(bookIds: string[]) {
return (state$: Observable<BooksState>) => state$
.let(getBookEntities())
.map(entities => bookIds.map(id => entities[id]));
}
他们在示例中使用 index.ts 桶来组合这些内容。
import { compose } from '@ngrx/core/compose';
export function getBooks(bookIds: string[]) {
return compose(fromBooks.getBooks(bookIds), getBooksState());
}
这个函数会将调用链接在一起,从右到左进行。首先调用getBooksState获取reducer状态,然后调用fromBooks.getBooks并传入你想要的bookid以及上一个“getBooksState”的状态,允许你对所需的选定状态进行映射。
在你的组件中,你可以导入这个函数并使用它来获取你想要的书籍。
myBooks$: Observable<Books> = this.store.let(getBooks(bookIds)))
这个返回的可观察对象会在每次存储更新时更新。
补充:因此,存储对象上的“let”运算符将当前可观察对象传递给由“getBooks”函数返回的函数,该可观察对象保存存储状态对象。
让我们更仔细地看一下。
export function getBooks(bookIds: string[]) {
return compose(fromBooks.getBooks(bookIds), getBooksState());
}
在这里,将两个函数传递给compose函数——fromBooks.getBooks(bookIds)和getBooksState()。compose函数允许将值传递到右侧的第一个函数中,并将该函数的结果传递到左侧的函数中,以此类推。因此,在这种情况下,我们将获取“getBooksState”返回的函数的结果,并将其传递到由函数“fromBooks.getBooks(bookIds)”返回的函数中,最终返回该结果。
这两个函数都接受一个Observable。对于由getBooksState()返回的函数,它将作为参数接受存储状态observable对象,从中映射/选择(map和select是彼此的别名)到我们关心的存储片段并返回新的映射observable。该映射observable将被传递到由fromBooks.getBooks(bookIds)函数返回的函数中。该函数期望状态片段observable。该函数通过仅提取我们关心的实体来进行新的映射。这个新的observable就是“store.let”调用最终返回的内容。
如果您需要更多澄清,请提问,我会尽力澄清。
https://github.com/ngrx/example-app