错误值更改后检查(状态管道中Angular2) [英] Error value has changed after checked (Stateful Pipe in Angular2)

查看:375
本文介绍了错误值更改后检查(状态管道中Angular2)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的管道将筛选学生的数组。这里的code( Plnkr

I have a simple Pipe that filter an array of students. Here's the code (Plnkr)

import {Pipe} from 'angular2/core';

@Pipe({
  name: 'sortByName',
  pure: false
})
export class SortByNamePipe {
  temp = [];
  // i = 0;
  transform (value, [queryString]) {
    // console.log(this.i++);
    // console.log(value, queryString);

    // This does not work
    this.temp = value.filter((student)=>(student)=>student.name.includes(queryString)))
    return value.map(function(val){ return val.name.toUpperCase()});

    // This works
    // this.temp.length = 0;
    // this.temp.push(...value.filter((student)=>student.name.includes(queryString)))        
    // return this.temp;
  }
}

正如你可以看到Plnkr,角抛出使用第一种方法的错误。

As you can see in Plnkr, Angular throws an error using the first method.

EXCEPTION: Expression 'students | sortByName:queryElem.value  in HelloWorld@7:6' has changed after it was checked. Previous value: 'SON,DAVID'. Current value: 'SON,DAVID' in [students | sortByName:queryElem.value  in HelloWorld@7:6]

为什么?

推荐答案

角有状态管道不能作出一定的优化,​​比它可以为无状态(或纯)管道。例如,如果管道是无状态的,那么它遵循了滤波器的输出只依赖于它的输入(离开 |管道: ARGS )。只要左或ARGS'没有改变,那么输出将不会改变。这使得当输入没有改变AngularJS安全地跳过管的执行

Angular cannot make certain optimizations for a stateful pipe, than it can for a stateless (or pure) pipe. For example, if a pipe is stateless, then it follows that the output of the filter only depends on its inputs (left | pipe:args). As long as 'left' or 'args' hasn't changed, then the output will not change. This allows AngularJS to safely skip the execution of the pipe when the inputs haven't changed.

有关有状态管,所述管的输出会发生变化,即使是相同的输入。

For a stateful pipe, the output of the pipe can change, even for the same inputs.

该错误是告诉你,数组引用发生了变化,它已被确认后的第一轮变化检测后:

The error is telling you that the array reference has changed, after it has been checked following the first round of change detection:

... has changed after it was checked. 
Previous value: 'SON,DAVID'. Current value: 'SON,DAVID'...

我修改你的第一个例子,preserve数组引用:

I've modified your first example to preserve the array reference:

// This now works
var $this = this; // save this
$this.temp.length = 0;
var tmp = value.filter((student)=>student.name.includes(queryString));
tmp.forEach(function (val) {$this.temp.push(val);});
return $this.temp;

正如马克指​​出,误差仅在开发模式下发生。如果更改为生产模式错误消失,而code正常工作。

As Mark pointed out, the error only occurs during development mode. If you change to production mode the error goes away, and the code works as expected.

[说明]

显然,开发者模式,角度会检查您的绑定两次,以确保他们不会改变。

Apparently, in dev mode, angular will check your bindings twice to make sure they're not changing.

https://github.com/angular/angular/issues/6006

https://github.com/angular/angular/issues/6005

的问题是,当一个结合改变第一轮变化的检测后,也不会引发新一轮的变化检测的。这是不可取的,因为绑定不会直到将来的某个一轮变化检测的更新。为了确保这种情况不会发生,角检查绑定两次的发展模式,并提出了一个运行时错误检测到变化时。

The problem is that when a binding changes after the first round of change detection, it will not trigger a new round of change detection. This is undesirable because the binding will not be updated until some future round of change detection. To ensure that this does not happen, Angular checks the bindings twice in development mode, and raises a run-time error when changes are detected.

更新Plunkr

这篇关于错误值更改后检查(状态管道中Angular2)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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