javascript - 为什么我们需要使用@ViewChild 从其他组件调用组件的功能?
问题描述
我的导师告诉我,“在 Angular 中,我们可以通过导入该服务来使用任何服务中定义的函数,但我们不能在任何其他组件中导入组件。要使用在任何其他组件中定义的函数,我们需要使用 @ViewChild(组件名称)。”
但是当我尝试在不使用@viewChild 的情况下调用其他组件中的某个组件的函数时,我成功了,并且没有发生任何错误。
请参考以下示例以了解该场景:
CASE1:不使用@ViewChild,在其他组件中调用组件的函数
假设我们有一个组件“testcomponent”,并且在该组件中我们有一个“hello”函数,如下所示:
测试组件.component.ts
import { Component, OnInit, ContentChild, ElementRef } from '@angular/core';
@Component({
selector: 'app-testcomponent',
templateUrl: './testcomponent.component.html',
styleUrls: ['./testcomponent.component.css']
})
export class TestcomponentComponent implements {
constructor(){}
hello(){
console.log("Hello ABC");
}
}
为了在“app”组件中使用“testcomponent”组件的“hello”功能,我尝试了以下方法:
app.component.ts
import { Component} from '@angular/core';
import { TestcomponentComponent } from './testcomponent/testcomponent.component';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements AfterViewInit{
constructor(private testcomponent : TestcomponentComponent ){};
ngAfterViewInit(){
this.testComponent.hello();
}
}
这里“Hello ABC”在控制台中打印,没有发生任何错误。
CASE2:使用@ViewChild 在其他组件中调用组件的函数
现在考虑我在“app.component.ts”文件中使用@ViewChild 调用“testcomponent”组件的“hello()”函数的情况:
import { Component, ElementRef, ViewChild, AfterViewInit} from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements AfterViewInit{
@ViewChild(TestcomponentComponent,{static:false}) viewChildOnComponentSelector : TestcomponentComponent;
ngAfterViewInit(){
this.viewChildOnComponentSelector.hello();
}
}
既然在 CASE1 中我能够在“app”组件中调用“testcomponent”的“hello()”方法,那么为什么我们需要像在 CASE2 中一样需要 @ViewChild 呢?
另外请解释一下,如果我们可以通过导入任何其他组件中的任何组件的功能来调用该组件(如在 CASE1 中),那么调用组件或服务的功能有什么区别?
解决方案
当您在构造函数中注入服务时,这是一个唯一的服务。如果你注入一个组件只注入一个“副本”,而不是你看到的组件,例如,如果你的组件有一个带有 [(ngModel)] 的输入,你永远无法达到输入的值。
这就是原因,因为它不被认为是注入组件的好方法(如果我们只能访问一个函数,为什么不使用一个简单的类?)
注意:如果您调用的是 .html 中的按钮,您可以简单地使用变量引用,例如,您的主组件如下:
<button (click)="child.hello()">click</button>
<app-child-component #child></app-child-component>
推荐阅读
- ios - 进入信标区域后开始位置更新监控 Swift
- java - Hibernate 与 Where 子句的一对一映射
- amazon-web-services - 如何在处理程序函数之外访问全局范围内的阶段
- powershell - 我可以从历史记录中重新运行 Power Automate 流实例吗?
- angular - Angular 真的需要集成 Odata 排序、过滤等功能吗?
- vue.js - 数据未显示在 html 中
- c++ - f.getline() 迭代器不增加
- flutter - Dart 在没有花括号的类中需要值
- reactjs - 在组件内调度后立即更新状态后立即更新状态
- g1ant - VS 2019 的 G1ANT SDK 安装