我有一项全球服务,可以拯救一个行为主体.行为主体存储一个array.我有一个筛选器组件,它发出该数组的新版本,我可以看到全局服务上的更改.但是,在行为主体用作异步管道的情况下,视图中的值不会更改.

以下是我的做法:

在我的全球服务中,我有一门行为学科

public dataArray$: BehaviorSubject<Data[]> = new BehaviorSubject(someData);

筛选器组件将全局服务扩展为:

export class FilterComponent extends GlobalDataService

然后,触发器Filter函数更改原始数据(作为筛选器的基点),并为行为主体提供要发出的新值:

public triggerFilter(option: string): void {...

在函数内部,如下所示:

const filteredData = someData.filter(item => item.array.includes(option));. this.dataArray$.next(filteredData);.

当在全局数据服务内部按如下方式订阅时:

constructor() { this.showcase$.subscribe((res) => console.log('service', res))}

我可以看到.Next方法正在被调用并打印出新的array.但是,使用它的任何位置的异步管道都不会向视图发出新值--因此过滤器无法工作……

<app-filter></app-filter>
<app-data-items></app-data-items>

在app-data-items中:

<ng-container *ngIf="dataArray$ | async as dataArray">
     <span *ngFor="let data of dataArray" [ngStyle]="{ 'background-image': 'url(' + data.background + ')' }">
         <app-data-details [data]="data"></app-data-details>
     </span>
</ng-container>

当行为主体的值发生变化时,该视图不会更新.我的假设是,一旦在视图上定义了异步管道,就会自动打开订阅,并在更改后更改值?如果我说错了,这就是异步管道的要点?

我用的是16号角,现在我正在挠头,不知道为什么这个不能用.我曾考虑触发某种形式的更改检测策略(cdRef等),但这似乎是使用异步时的反措施?这应该通过异步管道来处理吗?

有没有人曾经遇到过这个问题,可以提供一些指导?

推荐答案

The problem here is that your component is extending the GlobalDataService, thus creating a local copy of it. In this way its dataArray$ value will be different wrom the one in the service, because they are two different objects.
If you want to share information across components, you should use your service as a Singleton.

简而言之,您只需更新和读取所有组件中的GlobalDataService中的dataArray$,并在所有感兴趣的组件中注入相同的GlobalDataService实例.

100

export class GlobalDataService {
    public dataArray$: BehaviorSubject<Data[]> = new BehaviorSubject(someData);

    public filterData(option: string): void {
        const filteredData = doStuffWithOptions(options);
        this.dataArray$.next(filteredData);
    }}

100

export class FilterComponent {
    triggerFilter(option: string): void {
        // You modify the BehaviourSubject in the service
        this.publicDataService.filterData(option)
    }
}

100

export class DataItemsComponent  {
    // Here you are doing a shallow copy of the BehaviourSubject
    public dataArray$ = this.publicDataService.dataArray$
}
<ng-container *ngIf="dataArray$ | async as dataArray">
     <span *ngFor="let data of dataArray" [ngStyle]="{ 'background-image': 'url(' + data.background + ')' }">
         <app-data-details [data]="data"></app-data-details>
     </span>
</ng-container>

Angular相关问答推荐

如何取消针叶林输入的自动填充?

文件阅读器未正确给出某些CSV文件的结果

具有多重签名的Angular Mocking Service

为什么我的自定义.d.ts不起作用?LeaderLine不是构造函数

找不到模块webpack dev服务器

无法在单个元素上多次监听同一个事件

如何在 Angular RxJS 中替换订阅中的 subscrib?

npm install命令在基本Angular 应用程序的天蓝色构建管道中失败

Angular:如何设置 PrimeNG p-steps 组件中已完成步骤的样式?

如何使用指令以Angular 传递默认值

尽管模型中的变量发生了变化,但Angular 视图没有更新

Angular 2模板驱动表单访问组件中的ngForm

Angular [disabled]="MyBoolean" 没有工作

Angular 5 中服务的生命周期是什么

来自 ngFor 项的动态 routerLink 值给出错误Got interpolation ({{}}) where expression was expected

如何在Angular 4中为数字管道指定语言环境千位分隔符

Angular2 Base64 清理不安全的 URL 值

Angular将 Select 值转换为 int

Angular 2 filter/search 列表

没有 ChildrenOutletContexts 的提供者 (injectionError)