为了账号安全,请及时绑定邮箱和手机立即绑定

如何在Angular 2中获取与ElementRef关联的组件的参考

/ 猿问

如何在Angular 2中获取与ElementRef关联的组件的参考

守着星空守着你 2019-11-15 10:59:22

我的模板中包含以下组件:


<vector-editor  #scaleControl

                [x]="scaleX"

                [y]="scaleY"

                [z]="scaleZ" >               

</vector-editor>

该vector-editor结构如下:


export class VerticeControlComponent implements OnInit

{

    @Input() x: number;

    @Input() y: number;

    @Input() z: number;


    ...

}

在我的应用程序中,我获取了有关#scaleControl使用的参考


@ViewChild('scaleControl') scaleControl: ElementRef;

现在,如果我输出scaleControl到控制台,则会得到以下结果:

http://img1.mukewang.com/5dce14a10001562804590210.jpg

可以看出,引用不是null,并且组件的所有属性都在其中。我想访问这些属性,但是在代码中,scaleControlis 的实际类型是ElementRef而不是VectorEditorControl在输出中看到的。因此,我不允许TypeScript使用this.scaleControl.x。


我也试过ElementRef像这样


var temp = <VectorEditorControl>this.scaleControl

但我得到一个错误,告诉我,我不能投ElementRef来VectorEditorControl


最后,我尝试访问,this.scaleControl.nativeElement但未定义...


我在这里想念什么?


查看完整描述

3 回答

?
拉丁的传说

您应该了解有关使用@ViewChild属性装饰器的以下内容。


它使用以下元数据属性:


选择器 -用于查询的指令类型或名称。

读 -从查询元件读取的不同的令牌。

从源代码:


export interface ViewChildDecorator {

  /**

   * You can use ViewChild to get the first element or the directive matching 

   * the selector from the

   * view DOM. If the view DOM changes, and a new child matches the selector,

   * the property will be updated.

   *

   * View queries are set before the `ngAfterViewInit` callback is called.

   *

   * **Metadata Properties**:

   *

   * * **selector** - the directive type or the name used for querying.

   * * **read** - read a different token from the queried elements.

   */

  (selector: Type<any>|Function|string, {read}?: {read?: any}): any;

  new (selector: Type<any>|Function|string, {read}?: {read?: any}): ViewChild;

}

如果不提供read参数,@ViewChild()将返回:


组件实例(如果有)。

ElementRef 如果未应用任何组件,则为实例

如果设置了read属性,则与查询的元素有不同的标记

因此,如果您想ElementRef从属于angular2组件(VerticeControlComponent)的子项中获取,则需要使用明确地告诉read: ElementRef:


@ViewChild('scaleControl', {read: ElementRef}) scaleControl: ElementRef;

然后在ngAfterViewInit钩子内部或更高版本中,您可以进行编写this.scaleControl.nativeElement以获取DOM元素。


更新资料

我写得很早:


如果设置了read属性,则与查询的元素有不同的标记

现在,我想添加一下我们可以阅读的内容:


元素引用


模板引用


ViewContainerRef


提供者


这Provider是什么意思?


这意味着,如果我们在特定元素上定义了任何提供程序(在组件或指令中),那么我们可以读取它。


@Component({

  selector: 'child',

  template: `

   <h2>I'm child</h2>

  `,

  providers: [

    {

      provide: 'test', useValue: 'x'

    }

  ]

})

export class ChildComponent {


}

因此,在该组件的使用者中,我们可以编写


@ViewChild(ChildComponent, { read: 'test' }) providerToken: string;

获得价值x。


查看完整回答
反对 回复 2019-11-15
?
幕布斯7119047

在撰写本文时,我建议使用以下方法:


@ViewChild('scaleControl') scaleControl: ElementRef<VerticeControlComponent>;

然后,您可以访问这两种类型。


ElementRef:使用scaleControl

VerticeControlComponent:使用scaleControl.nativeElement


查看完整回答
反对 回复 2019-11-15
?
慕圣8478803

我两次收到此错误。一次输入我的主代码,第二次输入测试代码(规范)。

两次都缺少一些参考。Angular编译器(transpiler)在编译过程中未显示任何错误,但稍后,它不提供任何引用

  1. 我第一次在主代码abc.component.ts中遇到此错误。我记得这次,我们在此abc.component.ts中正确包含了此孩子所需的引用。该子组件来自另一个模块。仅在此子组件未包含在module.ts文件中后,错误才得以解决

    声明:[VectorEditorComponent,....],

  2. 第二次我们在规格文件中遇到了这个问题。我正在尝试验证是否应该设置子组件的属性。我没有得到子组件的实例,而是得到了ElementRef。同样,这里没有编译错误。这里的问题略有不同。我曾经使用过No_Errors_Schema。因此,尽管我们没有在spec文件中包含该组件,但是angular并没有抱怨,而是设置了ElementRef而不是子组件。当我们导入模块并将其提供到spec文件的测试平台设置中时,错误消失了。

在第二种情况下,我可以理解这是由于没有错误模式造成的。但是在第一种情况下,我认为Angular团队需要改进。没有任何关于为何未提供组件但提供ElementRef的提示。


查看完整回答
反对 回复 2019-11-15

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信