【问题标题】:Expression has changed after it was checked. Previous value: 'ngTemplateOutlet: undefined'. Current value: 'ngTemplateOutlet: [object Object]'检查后表达式已更改。以前的值:“ngTemplateOutlet:未定义”。当前值:'ngTemplateOutlet:[object Object]'
【发布时间】:2018-12-12 17:45:58
【问题描述】:

有这样一个错误:

错误错误:ExpressionChangedAfterItHasBeenCheckedError:表达式 检查后有变化。以前的值:'ngTemplateOutlet: 不明确的'。当前值:'ngTemplateOutlet: [object Object]'。

在 viewDebugError (core.js:9775)

在表达式ChangedAfterItHasBeenCheckedError (core.js:9753)

在 checkBindingNoChanges (core.js:9920)

在 checkNoChangesNodeInline (core.js:13970)

在 checkNoChangesNode (core.js:13942)

在 debugCheckNoChangesNode (core.js:14771)

在 debugCheckDirectivesFn (core.js:14673)

在 Object.eval [as updateDirectives] (ShowEventComponent.html:73)

在 Object.debugUpdateDirectives [as updateDirectives] (core.js:14655)

在 checkNoChangesView (core.js:13780)

她因此出现:

<tr *ngFor="let user of users">
    <ng-template [ngTemplateOutlet]="loadTemplate(user)" 
                [ngTemplateOutletContext]="{ $implicit: user}">
    </ng-template>
</tr>

我该如何解决?

我使用 Angular 5.2.0,rxjs 5.5.6

【问题讨论】:

标签: angular


【解决方案1】:

这与变更检测有关。你可以在这里读更多关于它的内容。我通过使用 ChangeDetectorRef 中的 detectChanges() 方法解决了这个问题,即

constructor(private cdr: ChangeDetectorRef) {}

  ngOnInit() {}

  ngAfterViewInit(): void {
    this.cdr.detectChanges();
  }

您需要实现 AfterViewInit 接口。

【讨论】:

  • 这有效,但不是立即生效,Angular 很奇怪,某种内部缓存系统,请稍等。
【解决方案2】:

您应该将TemplateRef 设置为AfterContentInit 函数

【讨论】:

    【解决方案3】:

    就像 Envil 发布的那样,您可以将 loadTemplate() 函数的内容包装到 setTimeout 中,例如:

        setTimeout(() => {
            yourTemplateLoadingMechanism();
        });
    

    但总的来说,我会避免在模板中调用函数,因为它们会被一遍又一遍地调用,这使得调试变得困难并降低了性能。相反,您可以预取所有模板并像往常一样提供它们作为双向绑定,甚至使用 rxjs Observablesasync 关键字,这样可以更有效地规避您的问题。

    【讨论】:

      【解决方案4】:

      我最近修复了一个类似的问题,但找不到太多帮助,所以我将提供一些帮助。

      首先,这仅在开发模式下发生,但这是一个严重的问题。当 Angular 运行变更检测时,它会跟踪其所有绑定值(例如 ngTemplateOutlet),然后将该值与变更检测周期结束后的值进行比较。

      您收到此错误的原因是您在 html 中有一个设置 [ngTemplateOutlet] 的方法。这会导致该方法 (loadTemplate(user)) 在每次发生更改检测时运行。这可能是该方法运行的 5 或 10 倍,这并不理想。

      第一次将值设置为未定义,并在随后的周期中更新该值。我猜 loadTemplate 正在返回一个 TemplateRef,但是当方法第一次运行时,没有定义 TemplateRef,这就是原因。

      有很多方法可以解决这个问题,我需要查看您的 component.ts 代码。但是有两个必须发生的变化。首先,您需要在不使用方法的情况下设置 [ngTemplateOutlet]。您可以使用组件 Observable 或组件字段。但其次,您还需要在正确的时间设置字段或可观察对象。您想延迟到定义模板。您可以在 ngOnInit 中执行此操作,方法是将设置字段的代码包装在 setTimeout() 中,或者如果使用 Observable,则使用 lettable rxjs delay(0)。

      再次,我需要查看 loadTemplate(user) 和 component.ts 中的逻辑,以准确显示如何安排它。

      你也可以从父组件中输入你需要的数据到这个组件中,然后将使用该数据的逻辑放在 [ngTemplate] 之后

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-01-10
        • 2018-01-11
        • 2020-06-16
        • 2021-01-31
        • 2019-05-22
        • 1970-01-01
        • 1970-01-01
        • 2017-07-09
        相关资源
        最近更新 更多