我的模板中有以下组件:

<vector-editor  #scaleControl
                [x]="scaleX"
                [y]="scaleY"
                [z]="scaleZ" >               
</vector-editor>

vector-editor的 struct 如下:

export class VerticeControlComponent implements OnInit
{
    @Input() x: number;
    @Input() y: number;
    @Input() z: number;

    ...
}

在我的应用程序中,我使用

@ViewChild('scaleControl') scaleControl: ElementRef;

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

enter image description here

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

我也试着这样投ElementRef

var temp = <VectorEditorControl>this.scaleControl

但是我收到一个错误,告诉我我不能把ElementRefVectorEditorControl

最后,我试图访问this.scaleControl.nativeElement,但它是未定义的...

我错过了什么?

推荐答案

关于使用@ViewChild属性decorator ,你应该知道以下几点.

它使用以下Metadata Properties:

  • selector-用于查询的指令类型或名称.
  • read-从查询的元素中读取不同的标记.

来自源代码:

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实例
  • 如果您 Select set read property,则与查询的元素不同

因此,如果你想从子元素身上得到ElementRef,即angular2分量(VerticeControlComponent),你需要用read: ElementRef明确地告诉他:

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

然后是inside ngAfterViewInit hook or later,你可以写this.scaleControl.nativeElement来得到DOM元素.

更新

我很早就写过:

  • 如果您 Select set read property,则与查询的元素不同

现在我想补充一下我们能读到的内容:

  • ElementRef

  • TemplateRef

  • ViewContainerRef

  • Provider

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.

100

另见:

Angular相关问答推荐

Goto锚定在嵌套容器中,具有溢出自动

我使用Ngrx的子集 Select 器不起作用

RFDC.CommonJS或AMD依赖项可能会导致优化救助ANGURAL PROCEMENT with ngx-charts lib

停靠的Angular 应用程序的Nginx反向代理无法加载assets资源

MAT-复选框更改事件未在onSubscriberCheck函数中返回选中的值

Angular 17多内容投影错误

VS代码中带Angular 17的缩进新控制流

当快速拖动光标时会丢失元素 - Angular

完成行为主体

错误:在@angular/core中找不到导出ɵivyEnabled(导入为ɵivyEnabled)

无法推送 Angular 项目 - Github

个人修改 Angular CLI - 创建新应用

Angular 服务decorator 提供在延迟加载的根效果

运行 npm 测试(Angular 2 单元测试)后无法读取未定义的属性 subscribe

Angular 2 - 什么是Root Scope?

无法从模块it was neither declared nor imported导出服务

unexpected token < 错误

有条件地将 RouterLink 或其他属性指令添加到 Angular 2 中的元素

@viewChild 不工作 - 无法读取未定义的属性 nativeElement

来自 chokidar (C:\) 的错误:错误:EBUSY:资源繁忙或锁定,lstat 'C:\DumpStack.log.tmp