我正在尝试访问在某些HTML中使用选择器创建的组件。我的印象(错误地看来)供应商会寻找现有的实例并在注入另一个组件时提供,但显然我误解了分层提供者创建过程。
在下面,我有一个组件,它在其模板HTML中使用一个选择器来创建TopLevelComponent的实例。
我试图通过创建提供程序并使用DI通过构造函数推送该实例来访问该TopLevelComponent。
(道歉,如果这段代码不完美,我刚刚提出了一个简单的例子。)
@component({
selector: 'my-app',
template: '<top-level-component></top-level-component>',
directives: [TopLevelComponent],
providers: [TopLevelComponent],
})
export class MyApp {
constructor( private topLevelComponent: TopLevelComponent) {
}
}
@component({
selector: 'top-level-component',
template: '',
})
export class TopLevelComponent {
constructor() {
console.log('CONSTRUCTED A TopLevelComponent...');
}
}
但是,不是将TopLevelComponent的一个实例传递给我的组件,而是获得两个(由调试日志中存在的'CONSTRUCTED A TopLevelComponent ...'的两个日志证明)。
如果我从构造函数中删除'private topLevelComponent:TopLevelComponent',我只获得该组件的一个实例,但我似乎无法掌握它。
所以我有两个问题
或
<top-level-component></top-level-component>
,我该如何将HTML注入应用以便正确呈现?还有第三个
我在想@ViewChild是正确的方法,因为(!)只会是这个组件的一个实例,但是因为它注入了许多不同的组件,我认为这是不可能的。
答案 0 :(得分:2)
如果将组件添加到providers: [...]
,则该组件将被视为普通类。如果DI在请求TopLevelComponent
时找到这样的提供者,则会创建组件类的实例@Component(...)
装饰器被忽略。
如果directives: [...]
中列出了某个组件,如果由于匹配选择器而实例化,DI会将它们作为组件和指令找到。
<强>更新强>
<component-to-inject #source></component-to-inject>
<component-to-receive [injectedComponent]="source"></component-to-receive>
与
export class ReceivingComponent {
@Input() injectedComponent: InjectingComponent;
ngOnInit() {
console.log(this.injectedComponent);
}
}
答案 1 :(得分:1)
为了获得对模板中存在的组件的引用,可以使用@ViewChild注释。
@ViewChild(TopLevelComponent)
private myTopLevelComponent:TopLevelComponent
这将为您提供角度在相应模板中找到的TopLevelComponent的第一个实例。
如果您有多个相同类型的组件但想要找到某个组件,则可以使用本地模板变量。
@ViewChild('templateVariableName')
private myTopLevelComponent:TopLevelComponent
你的html模板需要看起来像这样:
<top-level-component #templateVariableName></top-level-component>
最后: 如果您想要查找相同类型的所有组件,可以使用@ViewChildren注释。
@ViewChildren(TopLevelComponent)
private topLevelComponents:QueryList<TopLevelComponent>
这将为您提供模板中所有TopLevelComponents的列表。
为什么在您的示例中创建了两个实例?
使用providers数组并要求在构造函数中注入该类,告诉angular创建组件类的实例。 当angular解析您的模板时,会创建第二个实例。
请注意,通过构造函数注入的实例与模板中存在的实例不同。您对注入的实例所做的任何更改都不会反映在屏幕上。
要获得正确的实例,您需要按照我上面提供的步骤进行操作。
答案 2 :(得分:0)
angular2传递提供程序中的服务列表。服务是可重复使用的代码段。
可在任何指令/组件中使用的基本服务示例。
imports ...
@Injectable()
export class MyEmpService {
getAllEmployees() {
// hit database
// return employee list
}
getEmp(id: number) {
// hit database
// return employee data
}
}
Component是一个带有视图的指令。 Angular2传递指令中的组件列表。列表中的任何组件都可以在组件中使用。同样,它是可重用的代码,但有视图。 简单的例子: EmployeeComponent.ts
imports...
@Component({
selector: 'my-emp',
template: `
<button (click)="getEmpList()">Get All Emp</button>
<button (click)="getEmp(2)">Get Emp</button>
<div>
{{result | json}}
</div>
`,
providers: [MyEmpService]
})
export class EmployeeComponent{
private result:any = '';
constructor(private myEmpService: MyEmpService) { }
getEmpList(){
this.result = myEmpService.getAllEmployees();
}
getEmp(id: number){
this.result = myEmpService.getEmp(id);
}
}
AppComponent.ts
imports...
@Component({
selector: 'my-app',
template: `
<h1>Main Component</h1>
<my-emp></my-emp>
`,
directives: [EmployeeComponent]
})
export class AppComponent{ }