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扫描下方二维码关注公众号和小程序↓↓↓