如何手动触发更改事件 - angular2

时间:2017-07-06 06:48:35

标签: angular typescript angular2-template angular2-directives

鉴于以下内容:

@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上的更改。因此,我想在调用item方法时为updateItem手动发出更改事件。然后,使子组件即CompB重新渲染,就像角度检测到常规方式的变化一样。

目前,我所做的是为ngOnInit实施CompB方法,并通过updateItem链接在ViewChild方法中调用该方法。故事的另一部分是我的实际来源有像someArray这样的对象,我想在每个渲染中重置它。我不确定重新渲染重置someArray。目前,我正在使用ngOnInit方法重置它们。

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

由于

2 个答案:

答案 0 :(得分:10)

  

据我了解,除非完整的项目对象是   更改后,angular2无法识别项目的更改。

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

  

然后,使子组件,即CompB重新渲染,就好像   角度检测到常规方式的变化。

您不必特别做任何事情,因为您仍然会在DOM中进行更新。

手动更改检测

您可以插入更改检测器并按此触发:

@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();
    }
}

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

但是,它不会对您的情况产生任何影响,因为即使Angular未检测到item中的更改,仍会运行更改检测B组件和更新DOM

除非您使用ChangeDetectionStrategy.OnPush。在这种情况下,一种方法是在ngDoCheck的{​​{1}}钩子中进行手动检查:

CompB

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

答案 1 :(得分:0)

您可以在CompB中放置另一个输入,因此,要更改CompA中的项目属性时,只需更改此输入的值即可。

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

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