📅  最后修改于: 2023-12-03 14:55:16.079000             🧑  作者: Mango
使用Angular时,我们通常使用NgRx来管理应用程序的状态。NgRx包含一个强大的 Store
,它是一个可观察的状态容器,用于组件之间的通信和状态管理。在许多情况下,我们需要在Store中管理对象的数组。在本文中,我们将了解如何更新NgRx中数组中的对象以角度存储。此外,我们将使用TypeScript编写我们的代码。
我们首先需要初始化我们的Store
。我们将创建一个状态,其中包含一个类型为 Person
的数组。 Person
类型将定义一个人的属性,例如名字和年龄。
export interface Person {
name: string;
age: number;
}
export interface AppState {
people: Person[];
}
const initialState: AppState = {
people: []
};
export function reducer(state = initialState, action: any) {
return state;
}
如上所述,我们创建了一个名为 Person
的接口,并在 AppState
接口中定义了一个 people
数组,以存储我们的人。 initialState
将具有一个空数组。这个reducer实际上不会做任何事情,但我们将使用它来初始化我们的应用程序状态。
现在我们已经定义了我们的Store,我们将在其中添加一个人,同时更新数组中的一个现有人。我们将使用一个 updatePerson
动作来实现这一操作。该操作将依次接收要添加和更新的人。我们将首先检查该人是否已经存在于数组中。如果是,我们将更新该人的属性,否则我们将将该人添加到数组中。
export const UPDATE_PERSON = '[People] Update Person';
export class UpdatePerson implements Action {
readonly type = UPDATE_PERSON;
constructor(public payload: { person: Person }) {}
}
export function reducer(state = initialState, action: UpdatePerson) {
switch(action.type) {
case UPDATE_PERSON:
const people = [...state.people];
const personToUpdate = people.find(person => person.name === action.payload.person.name);
if (personToUpdate) {
Object.assign(personToUpdate, action.payload.person);
} else {
people.push(action.payload.person);
}
return { ...state, people };
default:
return state;
}
}
如上所述,我们首先在文件顶部定义了一个 UPDATE_PERSON
常量,用于将该动作绑定到我们的reducer。接下来,我们创建了一个Redux动作类UpdatePerson
,用于将要添加和要更新的人作为有效负载传递给reducer的操作。在我们的 reducer
函数中,我们处理 UPDATE_PERSON
动作,并根据需要更新数组中的人。我们使用 ...
运算符复制当前状态中的 people
数组。接下来,我们使用数组上的 find
方法查找当前文本输入的人员,以便可以在其中更新其属性。如果找到此人员,则我们将使用 Object.assign
方法更新对象,否则我们将使用 push
方法将新人员添加到数组中。最后,我们返回一个新状态对象,该对象包含更新的 people
数组和当前状态的其余部分。
现在我们已经完成了我们的Store的更新,我们将在组件中调用这个功能。只需导入我们的 UpdatePerson
操作并注入我们的 Store
。我们还将创建一个名为updatePerson
的函数来将调用绑定到按钮上。
import { Component } from '@angular/core';
import { Store } from '@ngrx/store';
import { AppState, Person } from './app.state';
import { UpdatePerson } from './app.reducer';
import { Observable } from 'rxjs';
@Component({
selector: 'app-root',
template: `
<h1>People</h1>
<ul>
<li *ngFor="let person of people$ | async">
{{ person.name }} - {{ person.age }} <button (click)="updatePerson(person)">Update</button>
</li>
</ul>
<button (click)="updatePerson({name: 'John', age: 30})">Add John</button>
`
})
export class AppComponent {
people$: Observable<Person[]>;
constructor(private store: Store<AppState>) {
this.people$ = store.select(state => state.people);
}
updatePerson(person: Person) {
const newPerson = { ...person, age: person.age + 1 };
this.store.dispatch(new UpdatePerson({ person: newPerson }));
}
}
如上所述,我们创建了一个 AppComponent
组件,用于渲染我们的人员数组和提供一个 updatePerson
函数。在我们的模板中,我们使用 *ngFor
循环遍历数组中的人员列表,以便可以渲染每个人,并在旁边放置一个 “Update” 按钮。我们还使用一个用于添加 “John” 的按钮调用了 updatePerson
函数。
在我们的组件构造函数中,我们注入了 Store
实例,并使用 store.select
选择 people
数组。也就是说,我们将订阅该 people
属性的 Observable
实例,并在 people$
属性上公开该 Observable
。最后,我们使用 updatePerson
函数调用 dispatch
方法来发出一个 UpdatePerson
操作,以更新我们的 Store
中的人员信息。
如上所述,我们已经了解了如何更新NgRx中数组中的对象以角度存储,并且已经使用TypeScript编写我们的代码来完成该操作。这使我们能够有效地管理Angular应用程序中的组件之间的状态,并使代码更具可维护性和可扩展性。