Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/28.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 角度4变化检测表达式ChangedTerrithasBeenCheckedError_Angular_Typescript_Angular2 Changedetection - Fatal编程技术网

Angular 角度4变化检测表达式ChangedTerrithasBeenCheckedError

Angular 角度4变化检测表达式ChangedTerrithasBeenCheckedError,angular,typescript,angular2-changedetection,Angular,Typescript,Angular2 Changedetection,我试图解决AngularJS中不存在的问题,因为$digest-循环检查所有内容 我正在尝试创建一个组件,它可以初始化自身(异步),并通知其周围的容器加载已经完成 我有一个伪表: > 在周围的组件(包含行)中,我有一个函数onClickRow(row),它可以切换行 在my component组件中,我想将row.isLoading设置为true(通知“父”行它正在加载),然后在API调用完成后将其设置为false @Input()数据:任意; 恩戈尼尼特(){ this.task.islo

我试图解决AngularJS中不存在的问题,因为
$digest
-循环检查所有内容

我正在尝试创建一个组件,它可以初始化自身(异步),并通知其周围的容器加载已经完成

我有一个伪表:


>
在周围的组件(包含
)中,我有一个函数
onClickRow(row)
,它可以切换

my component
组件中,我想将
row.isLoading
设置为true(通知“父”行它正在加载),然后在API调用完成后将其设置为false

@Input()数据:任意;
恩戈尼尼特(){
this.task.isload=true;//问题
setTimeout(()=>{//simulate API调用
this.task.isload=false;//没问题
}, 2000);
}
现在我得到了这个错误:
error:expressionChangedTerithasBeenCheckedError:Expression在被检查后发生了更改。以前的值:“未定义”。当前值:“true”。

我想这是因为更改从树上的
my component
ng container
,然后不是向下到
my table row

我有一个解决方法,我可以使用第二个
setTimeout()
,在
this.task.isLoading
的第一个设置周围,但是这会导致一些popin效果,如果可能的话,我想找到一个更干净的解决方案


有人有什么建议吗?这是如何实现的?

我找到了一个可以接受的解决方案

您可以将“父级”注入组件(类似于AngularJS中的
require

为此,您需要将
my table行
my detail行
合并为类似
my item行
的内容。这还有一个额外的好处,即您可以将切换逻辑放入组件中,而不必在每次使用时都重新实现它

my item row.component.html

<div
    class="item-row"
    (click)="onToggleDetail()"
>
    <div class="cell">...</div>

    <div *ngIf="isLoading" class="loading"></div>
</div>

<div
    *ngIf="isExpanded"
    [hidden]="!isInitialized"
    class="detail-row"
>
    ...
</div>
现在,您可以将其注入
我的组件
,如下所示:

my component.component.ts

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

@Component({...})
export class MyItemRowComponent {
    ...

    isInitialized: boolean = false;
    isLoading: boolean = false;
    isExpanded: boolean = false;

    constructor(private changeDetector: ChangeDetectorRef) { }

    onToggleDetail() : void {
        this.isExpanded = !this.isExpanded;
    }

    public startLoading() : void {
        this.isLoading = true;
        this.isInitialized = false;

        this.changeDetector.detectChanges(); // trigger re-evaluate
    }

    public stopLoading() : void {
        this.isLoading = false;
        this.isInitialized = true;

        this.changeDetector.detectChanges(): // trigger re-evaluate
    }
}
import { Component } from '@angular/core';
import { Input, Host, Optional } from '@angular/core';

import { MyItemRowComponent } from '...';

@Component({...})
export class MyComponentComponent {
    ...

    // Optional, because there may be a case where we want to use it outside of a row
    constructor(@Optional() @Host() private parent: MyItemRowComponent) { }

    ngOnInit() { // or ngAfterViewInit, doesn't matter
        if (this.parent) {
            this.parent.startLoading();
        }

        setTimeout(() => { // simulate API call
            if (this.parent) {
                this.parent.stopLoading();
            }
        }, 2000);
    }
}
这是我目前的解决方案

这会导致启动
my组件时出现不同的问题,即使它尚未展开,请参见此处:


非常详细地解释了这种行为。为什么不总是使用
任务初始化。isLoading=true
并且不从my component中设置它,而是在加载组件时只更新为
false
,这将按照您所说的异步完成,您将不会有这种情况problem@Maximus我不能将
isLoading=true
作为默认值,它控制
我的表格行的可见行为
(显示加载指示器)。这个链接很有帮助,但有点告诉我,除了承诺/暂停之外,我别无选择,因为我正在做一些我不应该做的事情。但是现在我想不出任何其他方法来实现这一点,在
my component
子组件中有一个包含所有逻辑的“哑”表/包装组件。