如何在观察网络的 Observables 上使用声明模式?
How to use a declarative pattern on Observables that watch the network?
我一直在尝试了解 rxjs 中的声明式 pattern/approach,根据我的理解,它不直接在打字稿本身中使用 .subscribe()
而是使用 async
管道.
我有一个 class 保存有关图像的数据,其中一些数据是 tags
属性,它是一个字符串数组。通过 UI 你可以 add/remove 标签到这个 属性。当您保存一个新项目时,该值通过 websocket 发送到服务器,套接字将发回所有项目标签的列表(包括新添加的标签)。
因此,我创建了一个侦听器,用于侦听 websocket 何时响应与图像标签相关的数据。当它看到此消息时,它应该更新此图像对象中的所有标签。
类似于下面的伪代码:
interface FileInfo {
tags: string[];
}
@Component({
template: `
<div *ngIf="image$ | async as image">
<div *ngFor="let tag of image.tags">{{tag}}</div>
</div>
`
})
export class MyComponent {
image = new BehaviorSubject<FileInfo | null>(null);
image$ = this.image.asObservable();
ngOnInit() {
this.websocket.on('tags:image').pipe(
map(i => i.data) // i.data is an array of strings
tap(strs => this.image.value = strs)
);
}
}
现在,当消息返回时,它应该更新图像对象并重新呈现组件。
如果不在 this.websocket.on()
上使用订阅,这 pattern/approach 怎么可能?这一切所做的就是监视网络并修改对象上的 属性。
我将上面的修改为这种模式,但我不太喜欢我现在在做 .next()
时必须管理多个 属性,这种方法似乎不对似乎很容易使 image.tags
与 tags$
.
的值不同步
@Component({
template: `
<div *ngIf="image$ | async as image">
<div *ngFor="let tag of tags$ | async">{{tag}}</div>
</div>
`
})
export class MyComponent {
image = new BehaviorSubject<FileInfo | null>(null);
image$ = this.image.asObservable();
tags = new BehaviorSubject<string[]>([]);
tags$ = merge(this.tags, this.websocket.on('tags:image')).pipe(
map(i => i.data) // i.data is an array of strings
);
ngOnInit() {
// I want to get rid of this subscribe too
// However this is the next
this.manageService.$collectionEvents.subscribe(event => {
this.image.next(event.image);
this.tags.next(event.image.tags);
});
}
}
它会像这样(我刚刚制作了一个可观察的 data$
来模拟您的网络套接字响应):
image$ = new Observable<FileInfo>();
ngOnInit() {
const data$ = of({ data: ['string1', 'string2', 'string3'] });
this.image$ = data$.pipe(
map((i) => {
return { tags: i.data };
})
);
}
在您的上下文中
image$ = new Observable<FileInfo>();
ngOnInit() {
this.image$ = this.websocket.on('tags:image').pipe(
map((i) => {
return { tags: i.data };
})
);
}
异步管道将自动订阅 image$
并在组件销毁时取消订阅。每当 observable 收到新值时,它也会处理更新 html。
这是一个 stackblitz,我在其中模拟每秒变化的可观察值:https://stackblitz.com/edit/angular-ivy-m2digv?file=src/app/app.component.ts
我一直在尝试了解 rxjs 中的声明式 pattern/approach,根据我的理解,它不直接在打字稿本身中使用 .subscribe()
而是使用 async
管道.
我有一个 class 保存有关图像的数据,其中一些数据是 tags
属性,它是一个字符串数组。通过 UI 你可以 add/remove 标签到这个 属性。当您保存一个新项目时,该值通过 websocket 发送到服务器,套接字将发回所有项目标签的列表(包括新添加的标签)。
因此,我创建了一个侦听器,用于侦听 websocket 何时响应与图像标签相关的数据。当它看到此消息时,它应该更新此图像对象中的所有标签。
类似于下面的伪代码:
interface FileInfo {
tags: string[];
}
@Component({
template: `
<div *ngIf="image$ | async as image">
<div *ngFor="let tag of image.tags">{{tag}}</div>
</div>
`
})
export class MyComponent {
image = new BehaviorSubject<FileInfo | null>(null);
image$ = this.image.asObservable();
ngOnInit() {
this.websocket.on('tags:image').pipe(
map(i => i.data) // i.data is an array of strings
tap(strs => this.image.value = strs)
);
}
}
现在,当消息返回时,它应该更新图像对象并重新呈现组件。
如果不在 this.websocket.on()
上使用订阅,这 pattern/approach 怎么可能?这一切所做的就是监视网络并修改对象上的 属性。
我将上面的修改为这种模式,但我不太喜欢我现在在做 .next()
时必须管理多个 属性,这种方法似乎不对似乎很容易使 image.tags
与 tags$
.
@Component({
template: `
<div *ngIf="image$ | async as image">
<div *ngFor="let tag of tags$ | async">{{tag}}</div>
</div>
`
})
export class MyComponent {
image = new BehaviorSubject<FileInfo | null>(null);
image$ = this.image.asObservable();
tags = new BehaviorSubject<string[]>([]);
tags$ = merge(this.tags, this.websocket.on('tags:image')).pipe(
map(i => i.data) // i.data is an array of strings
);
ngOnInit() {
// I want to get rid of this subscribe too
// However this is the next
this.manageService.$collectionEvents.subscribe(event => {
this.image.next(event.image);
this.tags.next(event.image.tags);
});
}
}
它会像这样(我刚刚制作了一个可观察的 data$
来模拟您的网络套接字响应):
image$ = new Observable<FileInfo>();
ngOnInit() {
const data$ = of({ data: ['string1', 'string2', 'string3'] });
this.image$ = data$.pipe(
map((i) => {
return { tags: i.data };
})
);
}
在您的上下文中
image$ = new Observable<FileInfo>();
ngOnInit() {
this.image$ = this.websocket.on('tags:image').pipe(
map((i) => {
return { tags: i.data };
})
);
}
异步管道将自动订阅 image$
并在组件销毁时取消订阅。每当 observable 收到新值时,它也会处理更新 html。
这是一个 stackblitz,我在其中模拟每秒变化的可观察值:https://stackblitz.com/edit/angular-ivy-m2digv?file=src/app/app.component.ts