我怎样才能听到角度2中代码的变化?

时间:2016-02-28 09:16:27

标签: javascript angular

我正在使用角度2.我有一个带输入的组件。 我希望能够在输入值更改时编写一些代码。 绑定工作正常,如果数据发生变化(从组件外部),我可以看到dom中有变化。

if (window.PhoneCallTrap) {
    PhoneCallTrap.onCall(function(state) {
        console.log("CHANGE STATE: " + state);

        switch (state) {
            case "RINGING":
                console.log("Phone is ringing");
                break;
            case "OFFHOOK":
                console.log("Phone is off-hook");
                break;

            case "IDLE":
                console.log("Phone is idle");
                break;
        }
    });
}

2 个答案:

答案 0 :(得分:3)

您可以使用生命周期挂钩ngOnChanges

export class MyComponent {
  _data: Data;
  @Input()
  set data(value: Data) {
    this.data = value;
  }
  get data() {
    return this._data;
  }

  constructor() {
  }

  ngOnChanges([propName: string]: SimpleChange) {
    // listen to changes of _data object and do something...
  }
}

在以下情况下触发此挂钩:

  

如果有任何绑定发生了变化

有关详细信息,请参阅以下链接:

答案 1 :(得分:0)

正如Thierry Templier's answer的评论中所提到的,ngOnChanges生命周期钩子只能检测对基元的更改。我发现通过使用ngDoCheck代替,您可以手动检查对象的状态,以确定对象的成员是否已更改:

A full Plunker can be found here。但这是重要的部分:

import { Component, Input } from '@angular/core';

@Component({
    selector: 'listener',
    template: `
        <div style="background-color:#f2f2f2">
            <h3>Listener</h3>
            <p>{{primitive}}</p>
            <p>{{objectOne.foo}}</p>
            <p>{{objectTwo.foo.bar}}</p>

            <ul>
                <li *ngFor="let item of log">{{item}}</li>
            </ul>
        </div>
    `
})
export class ListenerComponent {
    @Input() protected primitive;
    @Input() protected objectOne;
    @Input() protected objectTwo;

    protected currentPrimitive;
    protected currentObjectOne;
    protected currentObjectTwo;

    protected log = ['Started'];

    ngOnInit() {
        this.getCurrentObjectState();
    }

    getCurrentObjectState() {
        this.currentPrimitive = this.primitive;
        this.currentObjectOne = _.clone(this.objectOne);
        this.currentObjectTwoJSON = JSON.stringify(this.objectTwo);
    }

    ngOnChanges() {
        this.log.push('OnChages Fired.')
    }

    ngDoCheck() {
        this.log.push('DoCheck Fired.');

        if (!_.isEqual(this.currentPrimitive, this.primitive)){
            this.log.push('A change in Primitive\'s state has occurred:');
            this.log.push('Primitive\'s new value:' + this.primitive);
        }

        if(!_.isEqual(this.currentObjectOne, this.objectOne)){
            this.log.push('A change in objectOne\'s state has occurred:');
            this.log.push('objectOne.foo\'s new value:' + this.objectOne.foo);
        }

        if(this.currentObjectTwoJSON != JSON.stringify(this.objectTwo)){
            this.log.push('A change in objectTwo\'s state has occurred:');
            this.log.push('objectTwo.foo.bar\'s new value:' + this.objectTwo.foo.bar);
        }

        if(!_.isEqual(this.currentPrimitive, this.primitive) || !_.isEqual(this.currentObjectOne, this.objectOne) || this.currentObjectTwoJSON != JSON.stringify(this.objectTwo)) {
             this.getCurrentObjectState();
        }
    }

应该注意的是,Angular文档提供了关于使用ngDoCheck

的注意事项
  

虽然ngDoCheck挂钩可以检测到英雄的名字何时发生了变化,   它的成本可怕。这个钩子的频率很高 -   每次变化检测周期后无论发生何种变化   发生了。在此示例之前,它被称为二十多次   用户可以做任何事情。

     

这些初步检查大部分是由Angular首先触发的   在页面上的其他位置呈现不相关的数据。仅仅是入住   另一个输入框触发一个电话。相对较少的电话显示实际   对相关数据的更改。显然我们的实施必须非常   轻量级或用户体验将受到影响。