如何停止在 ngOnInit() 之前调用的 ngOnChanges
Posted
技术标签:
【中文标题】如何停止在 ngOnInit() 之前调用的 ngOnChanges【英文标题】:how to stop ngOnChanges Called before ngOnInit() 【发布时间】:2017-08-16 06:38:59 【问题描述】:在我的 Angular 应用程序中,我遇到了一种情况,即 ngOnchanges 仅应在输入绑定更改时调用。那么,有没有办法在 ngOnInit 之前停止执行 ngOnChanges。有没有办法做到这一点。 提前致谢。
【问题讨论】:
这是正常行为。查看 Angular 2 文档中的 Lifecycle Hooks。而不是ngOnChange
,你可以试试ngAfterViewInit()
,例如(Angular初始化组件的视图和子视图后响应)
是的,我知道。 ngoninit 执行后,有什么方法可以监听我的输入变化?
在ngOnInit()
之后,ngDoCheck()
被执行(但它会被执行多次)。如果您使用的是响应式表单,您可以保留 ngOnChange 并检查是否设置了表单字段 (if(this.form.get('yourField').value) ...
)。类似于你现在拥有的东西。
是的,我确实尝试过使用 ngdocheck,但它进入了一种无限循环。这不是一个表单,dataready 是我从另一个组件获得的输入,我想听听它的变化。
没有。但是,如果您提供有关您尝试解决的实际问题的信息,我们可能会提供其他方法来帮助您解决问题。
【参考方案1】:
您无法阻止这种行为,但您可以:
使用主题:
class Foo implements OnChanges,OnInit,OnDestroy
onChanges = new Subject<SimpleChanges>();
ngOnInit()
this.onChanges.subscribe((data:SimpleChanges)=>
// only when inited
);
ngOnDestroy()
this.onChanges.complete();
ngOnChanges(changes:SimpleChanges)
this.onChanges.next(changes);
使用布尔属性:
class Foo implements OnChanges,OnInit
initialized=false;
ngOnInit()
// do stuff
this.initialized = true;
ngOnChanges(changes:SimpleChanges)
if(this.initialized)
// do stuff when ngOnInit has been called
使用SimpleChanges
API
你也可以查看SimpleChange.isFirstChange()
方法:
isFirstChange() : boolean
检查新值是否是第一个分配的值。
class Foo implements OnChanges,OnInit
@Input()
bar:any;
ngOnInit()
// do stuff
ngOnChanges(changes:SimpleChanges)
if(!changes["bar"].isFirstChange())
// do stuff if this is not the initialization of "bar"
【讨论】:
我可以使用自己的数据类型模型来代替SimpleChanges
吗?
对不起,我不明白你的问题。
我的意思是:我有自己的模型公共数据:自己的;它模型与模板绑定。我怎样才能听到这个模型的任何变化?
此答案假定您有能力跳过第一个 ngOnChanges。这并不能解决问题。问题是如何在第一个 ngOnChanges 之前调用 ngOnInit。我认为这是一个设计错误,尤其是在使用可选参数时。
@cyberfly 这取决于您的需求,它并没有本质上更好。请注意,使用 ReplaySubject,您将获得初始化之前设置的数据,这不是我们在这里想要的。另请注意,您可以在常规的 Observable/Subject 上 publishReplay()
和 connect()
或 shareReplay()
获得相同的行为。【参考方案2】:
我发现一种可行的方法是基于输入值都具有先前值属性这一事实。如果之前未设置输入,则该值将为CD_INIT_VALUE
(作为字符串)。因此,您可以设置一个条件,即您在ngOnChanges
中的代码块应该仅在前一个值不是CD_INIT_VALUE
时运行。这是您正在测试所有输入值的示例:
ngOnChanges(changes: SimpleChanges)
let initialized: boolean = true;
for (let prop in changes)
if (changes[prop].previousValue.toString() === 'CD_INIT_VALUE')
initialized = false;
//we can break here since if any item is not initialized
//we will say the inputs are NOT initialized
break;
if (initialized)
//code you want to execute
可能有更优雅的解决方案,但我发现这是可行的。 这可能为时已晚,无法帮助您,但可能会帮助其他人,因为当我在谷歌上搜索时,我发现了这个问题。解决方案是我从调试中发现的。
【讨论】:
【参考方案3】:如果它对任何人有帮助,这里是我如何将@n00dl3 建议的isFirstChange()
解决方案实施到我的 AngularJS 应用程序的示例:
this.$onChanges = (changes) =>
if (!changes.value.isFirstChange())
// do stuff
;
【讨论】:
以上是关于如何停止在 ngOnInit() 之前调用的 ngOnChanges的主要内容,如果未能解决你的问题,请参考以下文章