Angular 2 – 在父级初始化之后将数据传递给Child组件

前端之家收集整理的这篇文章主要介绍了Angular 2 – 在父级初始化之后将数据传递给Child组件前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个父组件,它通过服务从服务器获取数据。我需要将一些数据传递给Child组件。

我一直试图用通常的@Input()传递这些数据,但是正如我所期望的那样,我在Child组件中得到的数据是未定义的。

父组件

  1. @Component({
  2. selector: 'test-parent',template: `
  3. <test-child [childData]="data"></test-child>
  4. `
  5. })
  6.  
  7. export class ParentComponent implements OnInit {
  8. data: any;
  9.  
  10. ngOnInit() {
  11. this.getData();
  12. }
  13.  
  14. getData() {
  15. // calling service and getting data
  16. this.testService.getData()
  17. .subscribe(res => {
  18. this.data = res;
  19. });
  20. }
  21. }

子组件

  1. @Component({
  2. selector: 'test-child',template: `
  3. <!-- Content for child.... -->
  4. `
  5. })
  6.  
  7. export class ChildComponent implements OnInit {
  8. @Input() childData: any;
  9.  
  10. ngOnInit() {
  11. console.log(childData); // logs undefined
  12. }
  13. }

我保持简单的例子,以显示我正在尝试做的事情。我的问题是,在初始化之后是否可以将数据传递给孩子。我不确定但在这种情况下双向数据绑定会有帮助吗?

更多调查

根据发布的答案,我尝试使用ngOnChanges生命周期钩子。我遇到的问题是更新数据时不会触发ngOnChanges函数。数据是一个对象,这就是我认为没有检测到更改的原因。

更新了子组件中的代码

  1. @Component({
  2. selector: 'test-child',template: `
  3. <!-- Content for child.... -->
  4. `
  5. })
  6.  
  7. export class ChildComponent implements OnChanges {
  8. @Input() childData: any;
  9.  
  10. ngOnChanges() {
  11. console.log(childData); // logs undefined
  12. }
  13. }

我已经尝试使用Angular团队的Plunker上的Live Examples进行测试,展示Lifecycle Hooks。在测试中,我更新了OnChangesComponent以传递一个对象,在更新对象时,示例中可以看到ngOnChanges未检测到更改。 (这也在question显示)

https://plnkr.co/edit/KkqwpsYKXmRAx5DK4cnV

似乎ngDoCheck可以帮助解决这个问题,但在我看来,从长远来看它不会有助于性能,因为这个Lifecycle Hook会检测到每个变化。

另外我知道我可以使用@ViewChild()来访问子组件并设置我需要的变量,但我不认为对于这个用例它更有意义。

发布更多代码以帮助解释更好

父组件

  1. @Component({
  2. selector: 'test-parent',template: `
  3. <test-child [childType]="numbers" [childData]="data" (pickItem)="pickNumber($event)">
  4. <template let-number>
  5. <span class="number" [class.is-picked]="number.isPicked">
  6. {{ number.number }}
  7. </span>
  8. </template>
  9. </test-child>
  10. <test-child [childType]="letters" [childData]="data" (pickItem)="pickLetter($event)">
  11. <template let-letter>
  12. <span class="letter" [class.is-picked]="letter.isPicked">
  13. {{ letter.displayName }}
  14. </span>
  15. </template>
  16. </test-child>
  17. <button (click)="submitSelections()">Submit Selection</button>
  18. `
  19. })
  20.  
  21. export class ParentComponent implements OnInit {
  22. data: any;
  23. numbersData: any;
  24. lettersData: any;
  25.  
  26. ngOnInit() {
  27. this.getData();
  28. }
  29.  
  30. getData() {
  31. // calling service and getting data for the game selections
  32. this.testService.getData()
  33. .subscribe(res => {
  34. this.data = res;
  35. setChildData(this.data);
  36. });
  37. }
  38.  
  39. setChildData(data: any) {
  40. for(let i = 0; i < data.sections.length; i++) {
  41. if(data.sections[i].type === 'numbers') {
  42. this.numbersData = data.sections[i];
  43. }
  44.  
  45. if(data.sections[i].type === 'letters') {
  46. this.lettersData = data.sections[i];
  47. }
  48. }
  49. }
  50.  
  51. pickNumber(pickedNumbers: any[]) {
  52. this.pickedNumbers = pickedNumbers;
  53. }
  54.  
  55. pickLetter(pickedLetters: any[]) {
  56. this.pickedLetters = pickedLetters;
  57. }
  58.  
  59. submitSelections() {
  60. // call service to submit selections
  61. }
  62. }

子组件

  1. @Component({
  2. selector: 'test-child',template: `
  3. <!--
  4. Content for child...
  5. Showing list of items for selection,on click item is selected
  6. -->
  7. `
  8. })
  9.  
  10. export class ChildComponent implements OnInit {
  11. @Input() childData: any;
  12. @Output() onSelection = new EventEmitter<Selection>;
  13.  
  14. pickedItems: any[];
  15.  
  16. // used for click event
  17. pickItem(item: any) {
  18. this.pickedItems.push(item.number);
  19.  
  20. this.onSelection.emit(this.pickedItems);
  21. }
  22. }

这或多或少都是我的代码。基本上我有一个处理子组件选择的父级,然后我将这些选择提交给服务。我需要将某些数据传递给孩子,因为我试图让孩子以服务所期望的格式返回该对象。这将有助于我不创建父组件中服务所期望的整个对象。此外,它会使子项重用,因为它会发回服务所期望的内容

更新

我感谢用户仍然在这个问题上发布答案。请注意,上面发布的代码对我有用。我遇到的问题是,在一个特定的模板中,我有一个拼写错误导致数据未定义。

希望它证明是有帮助的:)

由于数据在开始时未定义,您可以使用* ngIf =’data’推迟数据
  1. <div *ngIf='data'>
  2. <test-child [childData]="data"></test-child>
  3. </div>

或者,您可以在组件上实现ControlValueAccessor,并使用ngModelChange通过ngModel传递它

  1. <test-child [ngModel]="data?" (ngModelChange)="data? ? data= $event : null"></test-child>

猜你在找的Angularjs相关文章