【发布时间】:2017-05-01 08:35:41
【问题描述】:
我有一个父组件,它通过服务从服务器获取数据。我需要将其中一些数据传递给子组件。
我一直在尝试使用通常的 @Input() 传递这些数据,但是正如我所料,我在 Child 组件中获得的数据是 undefined。
示例
父组件
@Component({
selector: 'test-parent',
template: `
<test-child [childData]="data"></test-child>
`
})
export class ParentComponent implements OnInit {
data: any;
ngOnInit() {
this.getData();
}
getData() {
// calling service and getting data
this.testService.getData()
.subscribe(res => {
this.data = res;
});
}
}
子组件
@Component({
selector: 'test-child',
template: `
<!-- Content for child.... -->
`
})
export class ChildComponent implements OnInit {
@Input() childData: any;
ngOnInit() {
console.log(childData); // logs undefined
}
}
我使示例保持简单,以便显示我正在尝试做的事情。我的问题是初始化后是否可以将数据传递给孩子。我不确定,但在这种情况下双向数据绑定会有所帮助吗?
更多调查
按照我尝试使用 ngOnChanges 生命周期挂钩的发布答案。我遇到的问题是更新数据时没有触发ngOnChanges 函数。数据是一个对象,这就是我认为没有检测到更改的原因。
子组件中的更新代码
@Component({
selector: 'test-child',
template: `
<!-- Content for child.... -->
`
})
export class ChildComponent implements OnChanges {
@Input() childData: any;
ngOnChanges() {
console.log(childData); // logs undefined
}
}
我已经尝试使用来自 Angular 团队的 Plunker 上的 Live Examples 进行测试,展示了 Lifecycle Hooks。在测试中,我更新了 OnChangesComponent 以传递一个对象,如示例中所示,在更新对象时 ngOnChanges 未检测到更改。 (这在question中也有展示)
https://plnkr.co/edit/KkqwpsYKXmRAx5DK4cnV
似乎ngDoCheck 可以帮助解决这个问题,但在我看来,从长远来看,这对性能没有帮助,因为这个生命周期挂钩会检测到每一个变化。
我也知道我可以使用@ViewChild() 来访问子组件并设置我需要的变量,但我认为对于这个用例来说没有多大意义。
发布更多代码以帮助更好地解释
父组件
@Component({
selector: 'test-parent',
template: `
<test-child [childType]="numbers" [childData]="data" (pickItem)="pickNumber($event)">
<template let-number>
<span class="number" [class.is-picked]="number.isPicked">
{{ number.number }}
</span>
</template>
</test-child>
<test-child [childType]="letters" [childData]="data" (pickItem)="pickLetter($event)">
<template let-letter>
<span class="letter" [class.is-picked]="letter.isPicked">
{{ letter.displayName }}
</span>
</template>
</test-child>
<button (click)="submitSelections()">Submit Selection</button>
`
})
export class ParentComponent implements OnInit {
data: any;
numbersData: any;
lettersData: any;
ngOnInit() {
this.getData();
}
getData() {
// calling service and getting data for the game selections
this.testService.getData()
.subscribe(res => {
this.data = res;
setChildData(this.data);
});
}
setChildData(data: any) {
for(let i = 0; i < data.sections.length; i++) {
if(data.sections[i].type === 'numbers') {
this.numbersData = data.sections[i];
}
if(data.sections[i].type === 'letters') {
this.lettersData = data.sections[i];
}
}
}
pickNumber(pickedNumbers: any[]) {
this.pickedNumbers = pickedNumbers;
}
pickLetter(pickedLetters: any[]) {
this.pickedLetters = pickedLetters;
}
submitSelections() {
// call service to submit selections
}
}
子组件
@Component({
selector: 'test-child',
template: `
<!--
Content for child...
Showing list of items for selection, on click item is selected
-->
`
})
export class ChildComponent implements OnInit {
@Input() childData: any;
@Output() onSelection = new EventEmitter<Selection>;
pickedItems: any[];
// used for click event
pickItem(item: any) {
this.pickedItems.push(item.number);
this.onSelection.emit(this.pickedItems);
}
}
这或多或少是我拥有的代码。基本上,我有一个父组件处理来自子组件的选择,然后我将这些选择提交给服务。我需要将某些数据传递给孩子,因为我试图让孩子以服务期望的格式返回的对象。这将帮助我不要在父组件中创建服务所期望的整个对象。此外,它还可以使子代可重用,因为它会发回服务所期望的内容。
更新
感谢用户仍在发布有关此问题的答案。请注意,上面发布的代码对我有用。我遇到的问题是,在一个特定的模板中我有一个错字,导致数据为undefined。
希望它对你有所帮助:)
【问题讨论】:
-
在子组件中你应该通过引用 this.childData 来调用它
-
我想这就是为什么它甚至在子组件中也没有加载
标签: angular angular-components