Angular @ViewChild 操作 DOM
Angular About 3,437 words@ViewChild
基本语法:
@ViewChild([reference from template], {read: [reference type]});
挂载的是span
等简单HTML
元素,Angular
推断为ElementRef
类型。
挂载的是template
元素(ng-template
),Angular
推断为TemplateRef
类型。
一些引用类型如ViewContainerRef
就不可以被Angular
推断出来,所以必须在read
参数中显式声明。
ElementRef
使用#
在HTML
标签上标记,在Component
中使用@ViewChild
找到该元素引用。
@Component({
selector: 'sample',
template: `
<span #tref>I am span</span>
`
})
export class SampleComponent implements AfterViewInit {
@ViewChild("tref", {read: ElementRef})
tref: ElementRef;
ngAfterViewInit(): void {
// `I am span`
console.log(this.tref.nativeElement.textContent);
}
}
可以直接通过依赖注入,获取宿主元素的ElementRef
对象。
@Component({
selector: 'sample',
...
export class SampleComponent{
constructor(private hostElement: ElementRef) {
// <sample>...</sample>
console.log(this.hostElement.nativeElement.outerHTML);
}
}
TemplateRef
TemplateRef
是一个结构简单的抽象类(ng-template
),它的elementRef
属性是对其宿主元素的引用,它还有一个createEmbeddedView
方法。createEmbeddedView
方法非常有用,因为它可以创建一个视图(view
)并返回该视图的引用对象ViewRef
。
$implicit
和let-
之间是什么关系?
答:可以通过let-name
在ng-template
上定义局部变量。该name
字段只能在ng-template
内部使用。
<ng-template let-foo>
{{ foo }}
</ng-template>
相当于
<ng-template let-foo="$implicit">
{{ foo }}
</ng-template>
如果不使用$implicit
,则需要这样写
<ng-template let-foo='helloWorld'>
{{ foo }}
</ng-template>
ts
文件
this.tpl.createEmbeddedView({helloWorld: 'this is from demo'})
案例
demo.component.ts
@Component({
selector: 'app-demo',
template: `
<ng-container #vc></ng-container>
<ng-template #tpl let-data>
<app-another [data]="data">I am span in template</app-another>
</ng-template>
`
})
export class DemoComponent implements OnInit {
@ViewChild("vc", {static: true, read: ViewContainerRef})
vc: ViewContainerRef;
@ViewChild("tpl", {static: true})
tpl: TemplateRef<any>;
ngOnInit(): void {
let view = this.tpl.createEmbeddedView({$implicit: 'this is from demo'});
this.vc.insert(view);
}
ngAfterViewInit() {
let elementRef = this.tpl.elementRef;
console.log(elementRef.nativeElement.textContent);
}
}
another.component.ts
@Component({
selector: 'app-another',
template:
`
<div>{{data}}</div>
`,
})
export class ShippingComponent {
@Input()
data: any;
constructor(
) { }
}
ViewContainerRef
视图容器可以挂载一个或多个视图。
使用createComponent
动态创建Component
。(componentFactoryResolver
方法已过时)
使用instance.data
传递值,这里的instance
表示component
的实例,而data
是AnotherComponent
中定义的@Input()
字段data
。
@Component({
selector: 'app-demo',
template: `
<ng-container #vc></ng-container>
`
})
export class DemoComponent implements OnInit {
@ViewChild("vc", {static: true, read: ViewContainerRef})
vc: ViewContainerRef;
constructor(
private componentFactoryResolver: ComponentFactoryResolver
) {
}
ngOnInit(): void {
// let componentFactory = this.componentFactoryResolver.resolveComponentFactory(AnotherComponent);
// let componentInstance = this.vc.createComponent<AnotherComponent>(componentFactory);
let componentInstance = this.vc.createComponent(AnotherComponent);
componentInstance.instance.data = "from create component";
}
}
参考
————        END        ————
Give me a Star, Thanks:)
https://github.com/fendoudebb/LiteNote扫描下方二维码关注公众号和小程序↓↓↓