我一直在寻找解决方案。我尝试过@Input,@ Query,dynamicContentLoader,@ Inject,@ Inject(forwardRef(()但是还没有能够解决这个问题的一堆不同的东西。
我的示例结构:
parent.ts
import {Component} from 'angular2/core';
@Component({
selector : 'my-app',
directives : [Child],
template : `<parent-component></parent-component>`
})
export class Parent
{
private options:any;
constructor()
{
this.options = {parentThing:true};
}
}
child.ts
import {Component} from 'angular2/core';
@Component({
selector : 'parent-component',
template : `<child-component></child-component>`
})
export class Child
{
constructor(private options:any) <- maybe I can pass them in here somehow?
{
// what I am trying to do is get options from
// the parent component at this point
// but I am not sure how to do this with Angular 2
console.log(options) <- this should come from the parent
// how can I get parent options here?
// {parentThing:true}
}
}
这是我在DOM中的当前HTML输出,因此这部分按预期工作
<parent-component>
<child-component></child-component>
</parent-component>
问题摘要:
如何将选项从父组件传递到子组件并在子构造函数中提供这些选项?
答案 0 :(得分:6)
父对子是最简单的形式,但它在构造函数中不可用,仅在ngOnInit()
(或更高版本)中。
这只需要子组件中的@Input() someField;
并使用绑定,这可以从父级传递给子级。父项中的更新将在子项中更新(而不是其他方向)
@Component({
selector: 'child-component',
template'<div>someValueFromParent: {{someValueFromParent}}</div>'
})
class ChildComponent {
@Input() someValueFromParent:string;
ngOnInit() {
console.log(this.someValue);
}
}
@Component({
selector: 'parent-component',
template: '<child-component [someValueFromParent]="someValue"></child-component>'
})
class ParentComponent {
someValue:string = 'abc';
}
让它在构造函数中可用使用共享服务。共享服务被注入到两个组件的构造函数中。要使注入工作,服务需要在父组件中或以上注册,而不是在子组件中注册。这样两者都获得相同的实例。 在父级中设置一个值并在客户端中读取它。
@Injectable()
class SharedService {
someValue:string;
}
@Component({
selector: 'child-component',
template: '<div>someValueFromParent: {{someValueFromParent}}</div>'
})
class ChildComponent {
constructor(private sharedService:SharedService) {
this.someValue = sharedService.someValue;
}
someValue:string = 'abc';
}
@Component({
selector: 'parent-component',
providers: [SharedService],
template: '<child-component></child-component>'
})
class ParentComponent {
constructor(private sharedService:SharedService) {
sharedService.someValue = this.someValue;
}
someValue:string = 'abc';
}
更新
没有太大区别。对于DI,只能使用构造函数。如果你想要注入的东西,它必须通过构造函数。当进行额外的初始化(如正在处理的绑定)时,Angular会调用ngOnInit()
。例如,如果您进行网络调用,那么如果您在ngOnInit
中的构造函数中执行此操作并不重要,因为无论如何都会调度服务器(异步)。当前同步任务完成后,JavaScript将查找下一个计划任务并对其进行处理(依此类推)。因此,无论您将它放在何处,都可能在ngOnInit()
之后实际发送构造函数中启动的服务器调用。
答案 1 :(得分:1)
您可以使用@Input
参数:
import {Component,Input} from 'angular2/core';
@Component({
selector : 'parent-component',
template : `<child-component></child-component>`
})
export class Child {
@Input()
options:any;
ngOnInit() {
console.log(this.options);
}
}
请注意,options
的值在ngOnInit
中可用,而不在构造函数中。有关更多详细信息,请查看组件生命周期挂钩:
并提供如下所述的选项:
import {Component} from 'angular2/core';
@Component({
selector : 'my-app',
directives : [Child],
template : `<parent-component [options]="options"></parent-component>`
})
export class Parent {
private options:any;
constructor() {
this.options = {parentThing:true};
}
}
如果要实现自定义事件:child触发事件并通知父注册。使用@Output
。