【发布时间】:2017-11-27 05:33:42
【问题描述】:
我需要能够完全重新加载子组件。似乎实现这一点的最佳方法是使用带有布尔值的简单*ngIf;设置为false删除组件,设置为true重新初始化,即:
<app-child *ngIf="enabled"></app-child>
但是,似乎仅仅这样做还不足以快速删除/重新初始化组件:
reloadTree(){
this.enabled = false;
this.enabled = true; // doesn't work- child ngOnInit isn't called
}
相反,我必须使用setTimeout 才能使用:
reloadTree(){
this.enabled = false;
const self = this;
setTimeout(function(){
self.enabled = true;
}, 1);
}
我认为这与 Angular 呈现模板的方式有关?这不是特别优雅 - 任何人都可以提出更好的方法来实现我在这里尝试做的事情吗?谢谢
【问题讨论】:
-
为什么首先需要重新加载它。这似乎是一个设计问题。相反,您可能应该向它传递一个不同的输入,或者让它对从 observable 发出的事件做出反应。
-
您可能需要在标志切换之间主动点击角度变化检测。这个ChangeDetectionRef 在这里可能会有所帮助。注入它并在两者之间调用
this.ref.detectChanges。 -
我承认这有点小题大做。不值得进入这里但足以说我已经花了几天时间解决一个特定的问题,这似乎是解决它的唯一方法。 @BenediktSchmidt-谢谢,您能详细说明一下吗?
-
您当前需要使用 setTimeout 的问题是,角度可能永远不会注意到您已经更改了值。因此 DOM 保持不变,组件可能不会被破坏。我不是 100% 肯定,因为我不知道角度何时检测到变化,但是更改一个值并在下一行重新更改它可能太快了。并且 *ngIf 仅在 angular 获取变量的任何更改时更新。因此,我想您必须手动告诉 Angular 发生了一些变化。
-
澄清一下,您只想在调用 reloadTree() 函数后调用子组件的 ngOnInit 方法?您可以使用@ViewChild 直接调用子组件的方法。
标签: angular