【问题标题】:Angular @ViewChild not loading on Router Outlet loadAngular @ViewChild 未在路由器插座负载上加载
【发布时间】:2019-08-14 16:42:50
【问题描述】:

下面的屏幕有 4 个按钮,用于完成有关在组件之间传递数据的教程 (Sharing Data Between Angular Components - Four Methods)。

@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>

请告诉我为什么在第一次点击时该消息不可用。

【问题讨论】:

  • 父模板是什么样子的
  • 现在将其添加到问题中。
  • 您是否在日志中看到“检查后表达式已更改”之类的错误?
  • 控制台中没有显示错误。
  • 您是在开发模式还是产品模式下运行?错误将在 prod 模式下被抑制

标签: angular angular-decorator


【解决方案1】:

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

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

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

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

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

但这里的问题是您不应该尝试这样做并且显示出糟糕的架构。数据应该根据事件传递给父母,而不是实例化

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

【讨论】:

  • 如果你愿意的话,你可以相信 angularfirebase 在你的眼睛和耳朵上。路由器插座与此无关。演示视频更有可能是故意抑制错误。他们在一天结束时销售产品。
  • 感谢您的回复,我会接受您的回答,并提醒您,无论您多么聪明,对初学者编码人员的同情都应该始终是编码帮助网站上的首要任务,有点“工作”消除被困负面情绪的自我也不会受到伤害。谢谢
【解决方案2】:

为此使用activate 事件。

父组件:

<div class="container">
  <router-outlet (activate)="onActivate($e)"></router-outlet>
</div>

onActivate(componentRef) {
  componentRef.myFunc();
}

子组件:

myFunc() {
  console.log("my function");
}

【讨论】:

  • 我在多个地方都看到了这个,但 $e 是未定义的
猜你喜欢
  • 2017-04-07
  • 2020-10-03
  • 1970-01-01
  • 1970-01-01
  • 2018-05-29
  • 1970-01-01
  • 2018-07-28
  • 1970-01-01
  • 2016-12-30
相关资源
最近更新 更多