在阵列推Angular2全新看法 [英] Angular2 refreshing view on array push

查看:200
本文介绍了在阵列推Angular2全新看法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我似乎无法得到angular2视图上的Array.push功能进行更新,从setInterval的异步操作要求。

在code是这个角的setInterval 的plunkr例子

我想要做的是如下:

\r
\r

进口{查看,分量,引导,指导,ChangeDetectionStrategy,ChangeDetectorRef}从'angular2 / angular2\r
\r
@Component({选择:'CMP',changeDetection:ChangeDetectionStrategy.OnPush})\r
@View({模板:蜱`数:{{numberOfTicks}}`})\r
类CMP {\r
  numberOfTicks = [];\r
  \r
  构造函数(私人REF:ChangeDetectorRef){\r
    的setInterval(()=> {\r
      this.numberOfTicks.push(3);\r
      this.ref.markForCheck();\r
    },1000);\r
  }\r
}\r
\r
@零件({\r
  选择:应用程序,\r
  changeDetection:ChangeDetectionStrategy.OnPush\r
})\r
@视图({\r
  模板:`\r
    < CMP>< CMP>\r
  `\r
  指令:[CMP]\r
})\r
类应用{\r
}\r
\r
引导程序(App);

\r

<!DOCTYPE HTML>\r
< HTML和GT;\r
\r
< HEAD>\r
  <标题> angular2操场< /标题>\r
  <脚本SRC =HTTPS://$c$c.angularjs.org/tool​​s/traceur-runtime.js>< / SCRIPT>\r
  <脚本SRC =HTTPS://$c$c.angularjs.org/tool​​s/system.js>< / SCRIPT>\r
  <脚本SRC =HTTPS://$c$c.angularjs.org/tool​​s/typescript.js>< / SCRIPT>\r
  &所述;脚本数据需要=茉莉数据semver =2.2.1SRC =htt​​p://cdnjs.cloudflare.com/ajax/libs/jasmine/2.2.1/jasmine.js>&下; / SCRIPT>\r
  &所述;脚本数据需要=茉莉数据semver =2.2.1SRC =htt​​p://cdnjs.cloudflare.com/ajax/libs/jasmine/2.2.1/jasmine-html.js> < / SCRIPT>\r
  &所述;脚本数据需要=茉莉@ *数据semver =2.2.1SRC =htt​​p://cdnjs.cloudflare.com/ajax/libs/jasmine/2.2.1/boot.js> < / SCRIPT>\r
  \r
  &所述; SCRIPT SRC =config.js>&下; /脚本>\r
  <脚本SRC =HTTPS://$c$c.angularjs.org/2.0.0-alpha.37/angular2.min.js>< / SCRIPT>\r
  <脚本>\r
    System.import(应用)\r
      .catch(console.error.bind(控制台));\r
  < / SCRIPT>\r
\r
< /头>\r
\r
<身体GT;\r
  <应用>< /应用>\r
< /身体GT;\r
\r
< / HTML>

\r

\r
\r

以上code将正常工作,如果numberOfTicks只是一个数字,(如plunker原来的例子显示),但一旦我将其更改为一个数组,推送数据,也不会更新。

我似乎无法理解这是为什么。

以下行为类似于一个问题,尝试使用时,用新的数据点angular2更新图时,我有的setInterval / setTimeout的。

感谢您的帮助。


解决方案

您需要在其中添加元素后更新阵列全参考:

 构造函数(私人REF:ChangeDetectorRef){
    的setInterval(()=> {
      this.numberOfTicks.push(3);
      this.numberOfTicks = this.numberOfTicks.slice();
      this.ref.markForCheck();
    },1000);
  }
}

修改

该DoCheck界面还可以你感兴趣,因为它允许你插入自己的变化检测算法。

请参阅以下链接了解详情:

下面是一个例子:

  @Component({
  选择:自定义检查,
  模板:`
    < UL>
      <李* ngFor =日志#线> {{}线}< /李>
    < / UL>`
})
类CustomCheckComponent实现DoCheck {
  @input()列表:任何[];
  不同:有的话;
  日志= [];  构造函数(不同:IterableDiffers){
    this.differ = differs.find([])创建(空)。
  }  ngDoCheck(){
    VAR变化= this.differ.diff(this.list);
    如果(变更){
      changes.forEachAddedItem(R = GT; this.logs.push('加'+ r.item));
      changes.forEachRemovedItem(R = GT; this.logs.push('删除'+ r.item))
    }
  }
}

I can't seem to get angular2 view to be updated on an array.push function, called upon from a setInterval async operation.

the code is from this angular plunkr example of setInterval:

What i'm trying to do is as follows:

import {View, Component, bootstrap, Directive, ChangeDetectionStrategy, ChangeDetectorRef} from 'angular2/angular2'

@Component({selector: 'cmp', changeDetection: ChangeDetectionStrategy.OnPush})
@View({template: `Number of ticks: {{numberOfTicks}}`})
class Cmp {
  numberOfTicks = [];
  
  constructor(private ref: ChangeDetectorRef) {
    setInterval(() => {
      this.numberOfTicks.push(3);
      this.ref.markForCheck();
    }, 1000);
  }
}

@Component({
  selector: 'app',
  changeDetection: ChangeDetectionStrategy.OnPush
})
@View({
  template: `
    <cmp><cmp>
  `,
  directives: [Cmp]
})
class App {
}

bootstrap(App);

<!DOCTYPE html>
<html>

<head>
  <title>angular2 playground</title>
  <script src="https://code.angularjs.org/tools/traceur-runtime.js"></script>
  <script src="https://code.angularjs.org/tools/system.js"></script>
  <script src="https://code.angularjs.org/tools/typescript.js"></script>
  <script data-require="jasmine" data-semver="2.2.1" src="http://cdnjs.cloudflare.com/ajax/libs/jasmine/2.2.1/jasmine.js"></script>
  <script data-require="jasmine" data-semver="2.2.1" src="http://cdnjs.cloudflare.com/ajax/libs/jasmine/2.2.1/jasmine-html.js"></script>
  <script data-require="jasmine@*" data-semver="2.2.1" src="http://cdnjs.cloudflare.com/ajax/libs/jasmine/2.2.1/boot.js"></script>
  
  <script src="config.js"></script>
  <script src="https://code.angularjs.org/2.0.0-alpha.37/angular2.min.js"></script>
  <script>
    System.import('app')
      .catch(console.error.bind(console));
  </script>

</head>

<body>
  <app></app>
</body>

</html>

The above code will work properly if "numberOfTicks" is just a number, (as the plunker original example shows) but once I change it to an array and push data, it won't update.

I can't seem to understand why is that.

The following behaviour is similar to an issue I have when trying to update a graph in angular2 with new data points when using setInterval / setTimeout.

Thanks for the help.

解决方案

You need to update the whole reference of your array after adding an element in it:

  constructor(private ref: ChangeDetectorRef) {
    setInterval(() => {
      this.numberOfTicks.push(3);
      this.numberOfTicks = this.numberOfTicks.slice();
      this.ref.markForCheck();
    }, 1000);
  }
}

Edit

The DoCheck interface could also interest you since it allows you to plug your own change detection algorithm.

See this link for more details:

Here is a sample:

@Component({
  selector: 'custom-check',
  template: `
    <ul>
      <li *ngFor="#line of logs">{{line}}</li>
    </ul>`
})
class CustomCheckComponent implements DoCheck {
  @Input() list: any[];
  differ: any;
  logs = [];

  constructor(differs: IterableDiffers) {
    this.differ = differs.find([]).create(null);
  }

  ngDoCheck() {
    var changes = this.differ.diff(this.list);
    if (changes) {
      changes.forEachAddedItem(r => this.logs.push('added ' + r.item));
      changes.forEachRemovedItem(r => this.logs.push('removed ' + r.item))
    }
  }
}

这篇关于在阵列推Angular2全新看法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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