我的模板中有这个组件:
<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
输出到控制台,我会得到以下结果:
可以看出,引用不是null,并且我的组件的所有属性都在那里。我想访问这些属性,但在代码中,scaleControl
的实际类型为ElementRef
,而不是VectorEditorControl
,如输出中所示。因此,TypeScript不允许我使用this.scaleControl.x
。
我也尝试像这样投射ElementRef
var temp = <VectorEditorControl>this.scaleControl
但是我收到错误告诉我,我无法将ElementRef
投提VectorEditorControl
最后,我试图访问this.scaleControl.nativeElement
,但它未定义......
我在这里缺少什么?
答案 0 :(得分:80)
您应该了解使用@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
实例因此,如果你想从儿童角色2组件ElementRef
获得VerticeControlComponent
,你需要明确告诉使用read: ElementRef
:
@ViewChild('scaleControl', {read: ElementRef}) scaleControl: ElementRef;
然后在ngAfterViewInit挂钩或更高版本中,您可以编写this.scaleControl.nativeElement
来获取DOM元素。
我早写的:
如果设置了读取属性 ,则
- 来自查询元素的不同令牌
现在我想添加我们可以阅读的内容:
<强> ElementRef 强>
<强> TemplateRef 强>
<强> 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
。
<强> Example 强>
另见:
答案 1 :(得分:3)
在撰写本文时,我建议使用以下方法:
@ViewChild('scaleControl') scaleControl: ElementRef<VerticeControlComponent>;
然后您可以访问两种类型。
scaleControl
scaleControl.nativeElement
答案 2 :(得分:1)
我有两次这个错误。一旦进入我的主代码,第二次进入测试代码(规范)。
两次都缺少一些参考。 Angular编译器(转换器)在编译期间没有显示任何错误但稍后,悄悄地没有提供
的参考我第一次在主代码abc.component.ts中遇到此错误。我记得这一次,我们在这个abc.component.ts中正确地包含了这个孩子所需的引用。这个子组件来自另一个模块。仅在此子组件未包含在module.ts文件中
之后才解决该错误声明:[VectorEditorComponent,....],
第二次我们在spec文件中遇到此问题。我试图验证一些期望应该设置子组件的属性。我没有获得子组件的实例,而是获得了ElementRef。这里再次没有编译错误。这里的问题略有不同。我使用过No_Errors_Schema。因此,虽然我们没有在spec文件中包含该组件,但angular并没有抱怨,而是设置了ElementRef而不是子组件。导入模块时,错误消失,并在spec文件的testbed设置中提供。
在第二种情况下,我可以理解这是由于没有错误架构。但在第一种情况下,我认为Angular团队需要改进。没有任何关于为什么没有提供组件但提供ElementRef的提示。