首页 > 解决方案 > Angular @ViewChild 未在路由器插座负载上加载

问题描述

下面的屏幕有 4 个按钮,用于完成有关在组件之间传递数据的教程(在 Angular 组件之间共享数据 - 四种方法)。

我在@ViewChild 部分遇到问题。四个按钮下方有一个路由器链接,每个按钮上都填充了单击相关组件。 在此处输入图像描述

当我单击 @ViewChild 按钮时,组件显示但未填充消息,它是空的。

在此处输入图像描述

当我再次单击@ViewChild 按钮时,消息按预期填充。

在此处输入图像描述

我确定这不是@ViewChild 的预期结果。所以我需要知道它为什么这样做以及如何更正它,以便在第一次点击时可以看到消息。

该教程说:'我们需要实现 AfterViewInit 生命周期挂钩来接收来自孩子的数据',我已经完成了。

下面是我的父子代码。

家长

import { Component, ViewChild, AfterViewInit } from '@angular/core';
import { ChildComponent } from './child/child.component';

@Component({
  selector: 'app-data-view-child',
  templateUrl: './data-view-child.component.html',
  styleUrls: ['./data-view-child.component.scss']
})

export class DataViewChildComponent implements AfterViewInit {

  @ViewChild(ChildComponent, { static: false }) child;

  constructor() { }

  message: string;

  ngAfterViewInit() {
    this.message = this.child.message
  }

}

孩子

import { Component } from '@angular/core';

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.scss']
})

export class ChildComponent {


  message = 'Hola Mundo!';
  constructor() { }
}

父模板

<div class="parent-card">
  <h1>I am the Parent component</h1>
  <h2 class="tac">Message: {{ message }}</h2>
  <app-child></app-child>
</div>

请让我知道为什么该消息在第一次点击时不可用。

标签: angularangular-decorator

解决方案


这里的问题是违反单向数据流,这会阻止更改检测正确触发。单向数据流意味着在变更检测期间数据需要向上或向下流动您的组件树。实例化组件树是数据向下流动,但是在实例化过程中试图从子节点中提取数据意味着您违反了原则,将其拉回。Angular 不允许这样做,因为它可能会创建一个无限变化检测循环,其中父触发子,子触发父等等。

如果您在开发模式下运行,您会看到类似“检查后表达式更改”之类的错误......这意味着您孩子的某些东西在您的父母更改检测周期中导致您的父母发生了变化。

你可以做很多这样的骇人听闻的事情:

ngAfterViewInit() {
  setTimeout(() => {
    this.message = this.child.message;
  });
}

这将解决您的问题,因为超时将触发父级中的另一轮更改检测。

但这里的问题是你不应该尝试这样做并且显示出糟糕的架构。数据应该在响应事件而不是实例化时到达父级

演示闪电战:。https://stackblitz.com/edit/angular-zzc7r6?file=src/app/app.component.ts


推荐阅读