Angular 8 UI observable 未触发更改检测 - ChangeDetectionStrategy 设置为默认值

Angular 8 UI observable not triggering change detection - ChangeDetectionStrategy is set to default

我有一个容器组件,其中注入了一项服务。该服务包含一个可观察的。在容器组件的模板中,我使用异步管道将该可观察对象绑定到 child 组件的输入 属性。一切似乎都正常,除了我必须与 UI 交互才能触发更改检测并显示通过可观察对象推送的数据。

(不更新是指似乎:child 组件 html 中的 <ng-container *ngFor="let section of sections;"> 未执行)

我已经尝试了很多事情,包括在 parent 组件中创建另一个可观察对象,并通过该可观察对象从服务中继数据——但这只是一种故障排除措施,而且非常笨拙。我相信它有相同的结果。

注:

1. The service is pulling data from a .net backend via a socket (SignalR).
2. I am also using Angular Material's drag and drop library in this project.
3. **This post seems very similar**, but I can't discern a cause or solution from it: 
4. I mention 3 because that person was using angular material's infinite scrolling library and I am using drag and drop. Maybe something in that library is interfering with change detection.
5. There is no OnPush change detection anywhere in this project

服务:

export class DocumentCreationService {

  private library = new Subject<DocumentSection[]>();
  public library$ = this.library.asObservable();
...
  private registerOnServerEvents(): void {

  this.proxy.on('documentSectionsRetrieved', (result: DocumentSection[]) => {
        this.library.next(result);
    });
  }
...
  public retrieveDocumentSections = () => {
    this.proxy.invoke('getDocumentSections')
              .then(() => console.log("getDocumentSections completed"))
              .catch(err => console.error(err));
  }
...
}

容器 ts:

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.scss']
})
export class HomeComponent {
...
  constructor(public documentCreator: DocumentCreationService) { }
}

容器html:

<document-section-library #library [hidden]="selectedView !== 'library'" [sections]="documentCreator.library$ | async" [connectedDropTargets]="dropTargets">

Child 时间:

@Component({
  selector: 'document-section-library',
  templateUrl: './document-section-library.component.html',
  styleUrls: ['./document-section-library.component.scss']
})
export class DocumentSectionLibraryComponent {
...
  @Input()
  public sections: DocumentSection[];
...

Child html:

  <div class="document-section-library__contentarea" cdkDropList id="sectionLibrary" #sectionLibrary="cdkDropList" [cdkDropListConnectedTo]="connectedDropTargets" [cdkDropListData]="sections" (cdkDropListDropped)="onDrop($event)">

    <ng-container *ngFor="let section of sections;">

      <ng-template [ngIf]="section.content && section.content.length > 0" [ngIfElse]="table">

        <document-section-custom class="document-section" cdkDrag 
          [id]="section.id"
          [templateId]="section.templateId" 
          [name]="section.name" 
          [enabled]="section.enabled" 
          [content]="section.content">
        </document-section-custom>

      </ng-template>

      <ng-template #table>
        <document-section-table class="document-section" cdkDrag 
          [id]="section.id" 
          [templateId]="section.templateId"
          [name]="section.name" 
          [enabled]="section.enabled" 
          [content]="section.content">
        </document-section-table>
      </ng-template>

    </ng-container>

  </div>

我希望 UI 能够立即反映通过 observable 推送的数据,而无需单击某些内容或以其他方式与 UI 交互。

在这种情况下,我尝试使用可观察对象来执行此操作,因为我似乎也无法以任何其他方式让它工作。

最终,我真正想要的是在服务中只拥有一个 DocumentSection 数组作为 public 属性,通过服务上的方法更新该数组,并进行更改立即反映到数组中。我不确定我什至真的需要一个可观察的。我希望服务上的 属性 像组件上的本地 属性 一样。

所以两个问题:

  1. 这个变化检测问题是怎么回事,我该如何解决?

  2. 为什么我不能(或可以),只需在服务上创建一个 public 数组并正常绑定它(不通过异步管道)并让它在同一个环境中工作如果它是容器组件上的 public 属性 会怎样?

也许发生的事情是他们订阅(async 在容器视图中)发生在初始文档到达之后,所以 Angular 没有接收到该排放?

我会尝试改变:

private library = new Subject<DocumentSection[]>();

private library = new BehaviorSubject<DocumentSection[]>([]);

或者,您可以尝试完全不使用可观察对象,并绑定到通过 getter.

访问的基本数组
private _library = []; //  update when data is fetched
public get library() { return this._library || []; } // data-bind this

最终这似乎是某种 conflict/issue 与 Angular 和 JQuery and/or signalr(pre .net core)库 - 那个 signalr 库有对 JQuery 的依赖。我用更新的 .NET Core 版本替换了 signalr 库(当然我也将后端更新为 .NET Core)并删除了 JQuery 并且一切正常。我希望我能为其他遇到此问题的人找到更好的根本原因,但在与此抗争 48 小时后,我很高兴继续前进。

如果有人 thoughts/ideas 关于这两个库可能导致问题的原因,我仍然很感兴趣。