Angular2组件视图不断更新

时间:2015-12-14 18:36:57

标签: angularjs service dependency-injection components

我有一个Angular 2组件,它显示Items列表,并注册到发布事件的服务。问题是,即使我在收到事件时没有做任何事情,Angular也会更新视图(或者至少做一些事情,我猜,它不应该这样做。)

Here is a plunker

正如您在控制台中看到的,每次我的服务发布消息时,都会调用我的项目的“getTitle()”方法。

即使我没有注册到我的服务,如果我的组件没有实现MyServiceListener接口,每次服务获取消息时都会调用getTitle。如果我不在其构造函数中为我的组件提供服务,一切都很好。所以,我的依赖注入似乎有些问题,但是什么呢?

以下是plunker的相关代码:

我的服务及其听众界面:

export interface MyServiceListener {

    onMessage(_message: any);
}

export class MyService {

    private m_listener: MyServiceListener;

    constructor() {

          window.setInterval(() => {

              if (this.m_listener !== undefined) {

                  this.m_listener.onMessage("Hi");
              }

          }, 500);
    }

    setListener(_listener: MyServiceListener) { this.m_listener = _listener; }
}

Item类:

export class Item {

    m_title: string;

    constructor(_title: string) {

        this.m_title = _title;
    }

    getTitle(): string { console.log("getTitle"); return this.m_title; }
}

我的组件:

@Component({
    selector: 'my-app',
    template : `
      <div>
          <ul>
              <li *ng-for="#item of m_items">
                  {{item.getTitle()}}
              </li>
          </ul>
      </div>
    `
})
export class App implements TestBugAngularServiceListener {

    private m_items: Array<Item> = new Array<Item>();

    constructor(_communicationService: MyService) {

        this.m_items.push(new Item("A"));
        this.m_items.push(new Item("B"));
        this.m_items.push(new Item("C"));

        _communicationService.setListener(this);
    }

    onMessage(_message: any) {

    }
}

bootstrap(App, [MyService]).catch(err => console.error(err));

1 个答案:

答案 0 :(得分:0)

两篇文章:Change detection Angular immutability解释了很多关于Angular 2如何检测对象变化,以及如何遍历角度2中的组件树来执行数据绑定...... < / p>

在您的示例中,我认为您的组件“my-app”可以被视为“不可变”,因此将其“更改检测策略”更改为OnPush可以解决您的问题。

你可以这样写:

@Component({
    selector: 'my-app',
    changeDetection: ChangeDetectionStrategy.OnPush,
    template : `
      <div>
          <ul>
              <li *ng-for="#item of m_items">
                  {{item.getTitle()}}
              </li>
          </ul>
      </div>
    `
})

在将导入添加到ChangeDetectionStrategy后,“my-app”的数据绑定将不会在每个浏览器事件后计算,但仅在其输入发生更改时才会计算,所以永远不会...