先上代码:
app.component.ts:
import { Component, OnInit, ViewContainerRef, ViewChild, ComponentFactoryResolver } from '@angular/core';
import { TestComponent } from './test.component';
import { TestService } from './test.service';
@Component({
selector: 'app-root',
template: test
})
export class AppComponent implements OnInit {
//得到控件的视图部分,其实将ng-template换成div也是有这个属性的,即html控件都有view部分的
@ViewChild("alertContainer", { read: ViewContainerRef }) container: ViewContainerRef;
//加载已经声明的组件: 使用ComponentFactoryResolver,将一个组件实例呈现到另一个组件视图上
constructor(private dataservice: TestService,
private componentFactoryResolver: ComponentFactoryResolver) { }
ngOnInit() {
/*使用ComponentFactoryResolver动态加载组件,需要先了解如下概念:
1.ViewChild:属性装饰器,通过它可以获得视图上对应的元素;
2.ViewContainerRef:视图容器,可在其上创建、删除组件;
3.ComponentFactoryResolver:组件解析器,可以将一个组件呈现在另一个组件的视图上*/
let componentFactory = this.componentFactoryResolver.resolveComponentFactory(TestComponent);
this.container.clear();//清除视图
let componentRef = this.container.createComponent(componentFactory);//创建一个组件的实例
(componentRef.instance).data = this.dataservice.getDatas()[1];//给组件赋值
this.dataservice.getDatas()[0] = { name: 'form app name', bio: 'from app bio' }//改变service的数据,测试是否是同一个服务
}
}
app.module.te:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { TestModule } from './test.module';
@NgModule({
imports: [ BrowserModule ,
TestModule],
providers: [],
declarations: [ AppComponent],
bootstrap: [ AppComponent ]
})
export class AppModule {
constructor() {}
}
test.component.ts:
import { Component, Input} from '@angular/core';
import { TestService } from './test.service';
@Component({ {{data.bio}}
template: mymy TestComponent
{{data.name}}
})
export class TestComponent {
@Input()
data:any;
constructor(private dataservice:TestService) {}
test(){
this.data = this.dataservice.getDatas()[0];
}
}
test.module.te:
import { NgModule} from '@angular/core';
import { TestComponent } from './test.component';
import { TestService } from './test.service';
@NgModule({
declarations: [TestComponent],
entryComponents: [ TestComponent],
exports: [TestComponent],
providers:[TestService]
})
export class TestModule {
}
test.service.ts:
import { Injectable } from '@angular/core';
@Injectable()
export class TestService {
private datas = [
{name:'test pname',bio:'哈哈'},
{name:'test pname2',bio:'哈哈2'}
];
getDatas() {
return this.datas;
}
}
一些解释:
test的都很简单:
service是很简单的,平常写就行,加上@Injectable()就可以被注入了。
记得在test.module中提供出去,即在providers中提供出去。
TestComponent更简单,就是显示数据而已。这个没有selector,因此在module中记得加entryComponents: [ TestComponent],不然可能没法渲染成功。
app也比较简单:
把testmodule包含进来即可,这样在app模块中才能使用test模块的组件和服务了,并且这个服务是一个(如果都使用注入逇方式的话)
然后就是app控件了,解释看注释就行。
动态加载控件,再举另外一个小例子:
html文件:
ts文件:
@ViewChild('rrr', { read: ViewContainerRef }) adHost: ViewContainerRef;//得到div控件
constructor(
private componentFactoryResolver: ComponentFactoryResolver) {
//初始化,获取动态加载控件的必须参数
}
动态加载
ngOnInit() {
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(TestComponent);//TestComponent不说了,自己做一个吧
const componentRef = this.adHost.createComponent(componentFactory);
//把动态生成的控件加载到div上去
console.log(componentRef);
}
这样就成功了。