使用可观察存储和组件输入 Angular
Use an observable store and a component input with Angular
我使用 BehaviorSubject
开发了一个自定义 angular 商店,我使用的是这样的:
export class UserFaceComponent {
@Input()
public id: any;
public presence$: Observable<boolean>;
constructor(private _store: Store) { }
public ngOnInit() {
this.presence$ = this._store
.select(s => s.users.presences)
.pipe(
map(p => p.includes(this.id))
);
}
}
这样,当 store 发生变化时,presence$
observable 会发出一个新值。它运行良好,但是,传递给组件的 id
也可能会发生变化。假设页面上有一个用户列表,当用户选择其中一个时,它会更新传递给 UserFaceComponent
的变量 selectedUserId
。这将是与以前相同的组件,但 id
将被更新。
这意味着我必须在我的组件中创建一个主题,订阅 onChange
挂钩并在 id 更改时在该主题上发出。然后,我必须将这个 observable 与上面的合并,然后发出新值。
这可行,但非常麻烦,我不想被迫对使用这种方法制作的每个组件都这样做...我考虑了一段时间,但我找不到解决这个问题的另一种解决方案...
我多次遇到相同的要求,不幸的是,没有比您的 onChange
-subject
方法更简单的解决方案。我曾经读到有人建议使用 ObservableInput
装饰器,但从未实施过。
除了你的方法之外,还有另一种方法可以做到这一点,它并不简单,只是不同而已。这种替代方法使用输入 getter 和 setter 而不是 ngOnChanges
生命周期挂钩来更新主题。
private _id: BehaviorSubject<string> = new BehaviorSubject<string>();
@Input()
set id(value: string) {
this._id.next(value);
}
get id(): string {
return this._id.value;
}
如果您订阅 async
管道,您可以为您的变量分配一个新的 observable。 async
管道会自动取消订阅其当前的可观察对象,并在您为其输入分配新的可观察对象时订阅新的可观察对象。
export class UserFaceComponent {
@Input()
public id: any;
public presence$: Observable<boolean>;
constructor(private _store: Store) { }
ngOnChanges(changes: SimpleChanges) {
if (changes['id']) {
const currentId = changes['id'].currentValue
this.presence$ = this._store
.select(s => s.users.presences)
.pipe(
map(p => p.includes(currentId))
);
}
}
}
<div>{{ presence$ | async }}</div>
我使用 BehaviorSubject
开发了一个自定义 angular 商店,我使用的是这样的:
export class UserFaceComponent {
@Input()
public id: any;
public presence$: Observable<boolean>;
constructor(private _store: Store) { }
public ngOnInit() {
this.presence$ = this._store
.select(s => s.users.presences)
.pipe(
map(p => p.includes(this.id))
);
}
}
这样,当 store 发生变化时,presence$
observable 会发出一个新值。它运行良好,但是,传递给组件的 id
也可能会发生变化。假设页面上有一个用户列表,当用户选择其中一个时,它会更新传递给 UserFaceComponent
的变量 selectedUserId
。这将是与以前相同的组件,但 id
将被更新。
这意味着我必须在我的组件中创建一个主题,订阅 onChange
挂钩并在 id 更改时在该主题上发出。然后,我必须将这个 observable 与上面的合并,然后发出新值。
这可行,但非常麻烦,我不想被迫对使用这种方法制作的每个组件都这样做...我考虑了一段时间,但我找不到解决这个问题的另一种解决方案...
我多次遇到相同的要求,不幸的是,没有比您的 onChange
-subject
方法更简单的解决方案。我曾经读到有人建议使用 ObservableInput
装饰器,但从未实施过。
除了你的方法之外,还有另一种方法可以做到这一点,它并不简单,只是不同而已。这种替代方法使用输入 getter 和 setter 而不是 ngOnChanges
生命周期挂钩来更新主题。
private _id: BehaviorSubject<string> = new BehaviorSubject<string>();
@Input()
set id(value: string) {
this._id.next(value);
}
get id(): string {
return this._id.value;
}
如果您订阅 async
管道,您可以为您的变量分配一个新的 observable。 async
管道会自动取消订阅其当前的可观察对象,并在您为其输入分配新的可观察对象时订阅新的可观察对象。
export class UserFaceComponent {
@Input()
public id: any;
public presence$: Observable<boolean>;
constructor(private _store: Store) { }
ngOnChanges(changes: SimpleChanges) {
if (changes['id']) {
const currentId = changes['id'].currentValue
this.presence$ = this._store
.select(s => s.users.presences)
.pipe(
map(p => p.includes(currentId))
);
}
}
}
<div>{{ presence$ | async }}</div>