Typescript 角度2管道导致';。。。检查后已更改';开发错误

Typescript 角度2管道导致';。。。检查后已更改';开发错误,typescript,angular,Typescript,Angular,我知道为什么会抛出这个错误,但我不知道如何组织代码来修复它。问题就在这里 @Component({ selector: 'article', templateUrl: 'article.html', moduleId: module.id, directives: [Toolbar] }) export class Article { public toolbar: Array<IToolbarItem>; constructor()

我知道为什么会抛出这个错误,但我不知道如何组织代码来修复它。问题就在这里

@Component({
    selector: 'article',
    templateUrl: 'article.html',
    moduleId: module.id,
    directives: [Toolbar]
})
export class Article {
    public toolbar: Array<IToolbarItem>;

    constructor() {
        this.toolbar = [
            {
                css: 'ic-save',
                action: (item) => { },
                visible: false
            },
            <IDropdownItem>{
                css: 'ic-edit',
                items: [
                    {
                        css: 'ic-edit',
                        label: 'Edit Article',
                        action: (item) => { }
                    },
                    {
                        css: 'ic-edit',
                        label: 'Edit Content',
                        action: (item) => {
                            this.toolbar[0].visible = true;
                        }
                    }
                ]
            }
        ];
    }
}
因此,article组件使用工具栏数组传递到的工具栏组件,这反过来又使用visible管道过滤出visible属性设置为false的项目

运行
VisiblePipe
管道时,将抛出错误。因此,出于某种原因,管道转换代码在检测到更改后运行?为什么?

编辑

因此,我已经按照Gunter的建议更新了我的
VisiblePipe
管道,它正在工作

export class VisiblePipe implements PipeTransform {
    private previousValue: Array<IVisibleItem>;
    private cacheResult: Array<IVisibleItem>;

    transform(value: Array<IVisibleItem>) {
        if (!this.previousValue || !compareArrays(this.previousValue, value)) {
            this.previousValue = value.map(i => { return { visible: i.visible }   });
            this.cacheResult = value.filter(v => v.visible !== false);
        }

        return this.cacheResult;
    } 
}

function compareArrays(arrayOne: Array<IVisibleItem>, arrayTwo:  Array<IVisibleItem>) {
    if (arrayOne.length !== arrayTwo.length) {
        return false;
    }

    for (let i = 0, l = arrayOne.length; i < l; i++) {
       let arrayOneEntry = arrayOne[i];
       let arrayTwoEntry = arrayTwo[i];

       if (arrayOneEntry.visible !== undefined &&
            arrayTwoEntry.visible !== undefined &&
            arrayOneEntry.visible !== arrayTwoEntry.visible) {
            return false;
        }
    }

    return true;
}

interface IVisibleItem {
    visible: boolean
}
导出类VisiblePipe实现PipeTransform{
private-previousValue:数组;
私有缓存结果:数组;
转换(值:数组){
如果(!this.previousValue | |!comparararays(this.previousValue,value)){
this.previousValue=value.map(i=>{return{visible:i.visible}});
this.cacheResult=value.filter(v=>v.visible!==false);
}
返回此.cacheResult;
} 
}
函数比较数组(数组一:数组,数组二:数组){
if(arrayOne.length!==arrayTwo.length){
返回false;
}
for(设i=0,l=arrayOne.length;i

这真的是最好的/唯一的方法吗?感觉就像我自己在处理变化检测的某些方面

导致该错误的原因是,在
devMode
Angular runs中,每次转弯都会检测两次更改,并且管道会为两次后续调用返回不同的数组实例,即使输入值没有更改。 当设置为
pure:false时,这甚至是不允许的

若要修复此问题,请确保管道在输入未更改时为后续调用返回相同的数组实例

@Pipe({
    name: 'visible',
    pure: false
})
export class VisiblePipe implements PipeTransform {
    cached:any;
    transform(value) {
       if(value == this.value && this.resultCached) {
         return this.resultCached;
       }
       this.value = value;
       this.resultCached = (<Array<any>>value).filter(v => v.visible !== false);
       return this.resultCached;
    }
}
@管道({
名称:'可见',
纯:假
})
导出类VisiblePipe实现PipeTransform{
(a)任何;
转换(值){
if(value==this.value&&this.resultCached){
返回此.resultCached;
}
这个值=值;
this.resultCache=(用于检查数组中的项是否已添加、删除或替换。

这仍然不包括数组中包含的项中的属性更改。

这个表达式是什么
这个缓存;
是打字错误还是没问题?我认为无论
缓存到哪里,它都应该是
结果缓存的
。我认为
这个.cached
应该是
这个.value
(固定)但很久以前我就调查过了……很抱歉造成了混乱。
export class VisiblePipe implements PipeTransform {
    private previousValue: Array<IVisibleItem>;
    private cacheResult: Array<IVisibleItem>;

    transform(value: Array<IVisibleItem>) {
        if (!this.previousValue || !compareArrays(this.previousValue, value)) {
            this.previousValue = value.map(i => { return { visible: i.visible }   });
            this.cacheResult = value.filter(v => v.visible !== false);
        }

        return this.cacheResult;
    } 
}

function compareArrays(arrayOne: Array<IVisibleItem>, arrayTwo:  Array<IVisibleItem>) {
    if (arrayOne.length !== arrayTwo.length) {
        return false;
    }

    for (let i = 0, l = arrayOne.length; i < l; i++) {
       let arrayOneEntry = arrayOne[i];
       let arrayTwoEntry = arrayTwo[i];

       if (arrayOneEntry.visible !== undefined &&
            arrayTwoEntry.visible !== undefined &&
            arrayOneEntry.visible !== arrayTwoEntry.visible) {
            return false;
        }
    }

    return true;
}

interface IVisibleItem {
    visible: boolean
}
@Pipe({
    name: 'visible',
    pure: false
})
export class VisiblePipe implements PipeTransform {
    cached:any;
    transform(value) {
       if(value == this.value && this.resultCached) {
         return this.resultCached;
       }
       this.value = value;
       this.resultCached = (<Array<any>>value).filter(v => v.visible !== false);
       return this.resultCached;
    }
}