javascript - 在 QueryList.changes 上更改 ContentChildren 模型

标签 javascript angular

假设我有一个带有@ContentChildren(Child) children 的父组件。假设每个 Child 在其组件类中都有一个 index 字段。当 parent 的 child 发生变化时,我想使这些 index 字段保持最新,如下所示:

this.children.changes.subscribe(() => {
  this.children.forEach((child, index) => {
    child.index = index;
  })
});

但是,当我尝试执行此操作时,出现“ExpressionChangedAfter...”错误,我猜这是因为此 index 更新发生在更改周期之外。这是一个演示此错误的 stackblitz:https://stackblitz.com/edit/angular-brjjrl .

我该如何解决这个问题?一种明显的方法是在模板中简单地绑定(bind) index。第二种明显的方法是在更新其索引时为每个子项调用 detectChanges()。假设这两种方法我都做不到,还有其他方法吗?

最佳答案

如前所述,错误来自更改周期评估 <div>{{index}}</div> 后值的更改。 .

More specifically, the view is using your local component variable index to assign 0... which is then changed as a new item is pushed to the array... your subscription sets the true index for the previous item only after, it has been created and added to the DOM with an index value of 0.


setTimout.pipe(delay(0)) (这些本质上是同一件事)之所以有效,是因为它使更改与 this.model.push({}) 的更改周期相关联。发生在...没有它的地方,更改周期已经完成,并且单击按钮时,上一个周期中的 0 在新/下一个周期中更改。

设置持续时间 500 ms 到 setTimeout 方法,你会看到它真正在做什么。

 ngAfterContentInit() {
    this.foos.changes.pipe(delay(0)).subscribe(() => {
      this.foos.forEach((foo, index) => {
        setTimeout(() => {
          foo.index = index;
        }, 500)
      });
    });
  }
  • 它确实允许在元素呈现后设置值 DOM,同时避免错误但是,你不会有值(value) 在构造函数或 ngOnInit 期间在组件中可用如果 你需要它。

FooComponent 中的以下内容将始终导致 0setTimeout解决方案。

ngOnInit(){
    console.log(this.index)
  }

Passing the index as an input like below, will make the value available during the constructor or ngOnInit of FooComponent


您提到不想绑定(bind)到模板中的索引,但不幸的是,这是在元素呈现在 DOM 上之前传递索引值的唯一方法,默认值为 0。在你的例子中。

您可以在 FooComponent 中接受索引输入

export class FooComponent  {
  // index: number = 0;
  @Input('index') _index:number;

然后将循环中的索引传递给输入

<foo *ngFor="let foo of model; let i = index" [index]="i"></foo>

然后在 View 中使用输入

selector: 'foo',
  template: `<div>{{_index}}</div>`,

This would allow you to manage the index at the app.component level via the *ngFor, and pass it into the new element on the DOM as it is rendered... essentially avoiding the need to assign the index to the component variable, and also ensuring the true index is provided when the change cycle needs it, at the time of render / class initialization.

堆栈 Blitz

https://stackblitz.com/edit/angular-ozfpsr?embed=1&file=src/app/app.component.html

关于javascript - 在 QueryList.changes 上更改 ContentChildren 模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55286309/

相关文章:

css - ionic 2 : Beta 8 - scrollable content area cutting off button at bottom

angular - RXJS 获取 ReplaySubject 的当前值

javascript - 如何通过屏幕阅读器读取输入然后标记?

javascript - 如何通过 Angular 检查空格键事件?

angular - 以 Angular 2 重置输入值

javascript - 根据选中的复选框显示/隐藏部分

javascript - 在 Angular Highcharts 折线图中添加自定义按钮

javascript - ng-repeat 在 Angular.js 中生成额外的 td

javascript - 基于 JavaScript 文件上的 random() 执行不同的函数

javascript - Express js 路由器不工作