如何手动触发更改事件 - angular2 [英] How to trigger a change event manually - angular2

查看:38
本文介绍了如何手动触发更改事件 - angular2的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定以下组件:

@Component({
    selector: 'compA',
    template:  template: `<compB [item]=item></compB>`
})
export class CompA {
    item:any;
    updateItem():void {
        item[name] = "updated name";
    }
}

@Component({
    selector: 'compB',
    template:  template: `<p>{{item[name]}}</p>`
})
export class CompB implements OnInit{
    @Input() item: any;
    someArray: any[];

    ngOnInit():void {
        someArray.push("something");
    }
}

据我所知,除非完整的 item 对象被更改,否则 angular2 无法识别 item 上的更改.因此,当调用 updateItem 方法时,我想为 item 手动发出更改事件.然后,使子组件,即 CompB 重新渲染,就好像 angular 以常规方式检测到变化一样.

As far as I understood that unless the complete item object is changed, angular2 does not recognize the changes on item. Therefore, I'd like to emit a change event manually for item when the updateItem method is called. And afterwards, make the child component i.e. CompB re-rendered as if angular detected a change in the regular way.

目前,我所做的是实现CompBngOnInit方法,并通过方法在updateItem方法中调用该方法>ViewChild 链接.故事的另一部分是我的实际源有像 someArray 这样的对象,我想在每次渲染中重置它们.不过,我不确定重新渲染是否会重置 someArray.目前,我正在 ngOnInit 方法中重置它们.

Currently, what I have done is to implement the ngOnInit method of for CompB and call that method inside updateItem method through a ViewChild link. Another part of the story is that my actual source has objects like someArray which I'd like to be reset in each render. I'm not sure re-rendering resets someArray though. Currently, I'm resetting them in the ngOnInit method.

所以,我的问题是:如何触发重新渲染以更改父对象更深层次的元素?

So, my question is: how do I trigger re-rendering for changes on deeper elements of a parent object?

谢谢

推荐答案

据我所知,除非完整的项目对象是已更改,angular2 无法识别项目上的更改.

As far as I understood that unless the complete item object is changed, angular2 does not recognize the changes on item.

事情并没有那么简单.您必须区分在对象发生变异时触发 ngOnChanges 和子组件的 DOM 更新.Angular 无法识别 item 已更改并且不会触发 ngOnChanges 生命周期钩子,但是如果您引用 的特定属性,DOM 仍会更新模板中的项目.这是因为保留了对对象的引用.因此有这种行为:

It's not all that straightforward. You have to distinguish between triggering ngOnChanges when object is mutated and DOM update of the child component. Angular doesn't recognize that item is changed and doesn't trigger a ngOnChanges lifecycle hook, but the DOM will still be updated if you reference particular property of the item in the template. It's because the reference to the object is preserved. Therefore to have this behavior:

然后,使子组件,即 CompB 重新渲染,好像angular 以常规方式检测到变化.

And afterwards, make the child component i.e. CompB re-rendered as if angular detected a change in the regular way.

您不需要做任何特别的事情,因为您仍然会在 DOM 中进行更新.

You don't have to do anything in particular because you will still have update in the DOM.

您可以插入一个变更检测器并像这样触发它:

You can insert a change detector and trigger it like this:

@Component({
    selector: 'compA',
    template:  template: `<compB [item]=item></compB>`
})
export class CompA {
    item:any;
    constructor(cd: ChangeDetectorRef) {}

    updateItem():void {
        item[name] = "updated name";
        this.cd.detectChanges();
    }
}

这会触发当前组件及其所有子组件的更改检测.

This triggers change detection for the current component and all its children.

但是,它不会对你的情况产生任何影响,因为即使 Angular 没有检测到 item 中的变化,它仍然运行变化检测strong> 用于子 B 组件并更新 DOM.

But, it won't have any effect in your case because even though Angular doesn't detect change in item it still runs change detection for the child B component and updates the DOM.

除非您使用 ChangeDetectionStrategy.OnPush.在这种情况下,一种方法是在 CompBngDoCheck 钩子中进行手动检查:

Unless you use ChangeDetectionStrategy.OnPush. In this case a way to go for you would be to do a manual check in the ngDoCheck hook of the CompB:

import { ChangeDetectorRef } from '@angular/core';

export class CompB implements OnInit{
    @Input() item: any;
    someArray: any[];
    previous;

    constructor(cd: ChangeDetectorRef) {}

    ngOnInit():void {
        this.previous = this.item.name;
        someArray.push("something");
    }

    ngDoCheck() {
      if (this.previous !== this.item.name) {
        this.cd.detectChanges();
      }
    }
}

您可以在以下文章中找到更多信息:

You can find more information in the following articles:

这篇关于如何手动触发更改事件 - angular2的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆