【问题标题】:Angular2 way to update data in nested component from parent componentAngular2从父组件更新嵌套组件中数据的方法
【发布时间】:2017-04-28 16:51:37
【问题描述】:

我有两个嵌套组件:grid-containergrid-component

grid-container中,grid-component初始化如下:

<grid [title]="'This is the grid title'" [data]="data"></grid>

数据已初始化。使用事件,可以在grid-container 中获取grid-component 中更新的data。直到这里对我来说很明显。但是,我们通常应该在 Angular 2 中做什么来从容器组件(grid-container)更新嵌套组件(在本例中为 grid-component)中的 data

更具体地说,(或作为说明)我需要一个在容器组件 (grid-container) 中添加项目的函数,该函数将应用于 data 中的 grid-component

ps:它不是像in this question 那样的双向数据绑定,这也不适用于这个问题。

编辑:

export class GridComponent{ //child component
  @Input() data:any;
}

import { GridComponent } from 'somewhere';
export class GridContainer{ //parent component
  data:any = [{/*an initialized object which is visible in child component*/}]

  addItem(){
    data.push({/*an item is added*/};
    //PROBLEM IS THE NEWLY ADDED ITEM IS NOT VISIBLE IN GridComponent class.
  }
}

【问题讨论】:

    标签: angular angular-components


    【解决方案1】:

    你的问题不清楚。请提供您的 HTML 示例。 如果您有父子关系,那么它是 2 路数据绑定。

    @Component({
        template:`
            <grid-component>
                <grid-component [(data)]="gridData"></grid-component>
                <input type="button" label="Update Parent" (click)="updateData()" />
                <label>{{gridData.someCounter}}</label>
            </grid>
        `
    })
    class GridComponent{
        gridData: any = {
            someCounter = 1;
        };
    
        updateData() {
            this.gridData.someCounter++;
        }
    }
    
    @Component({
        template:`
            <input type="button" label="Update Child" (click)="updateData()" />
            <label>data.someCounter</label>
        `
    })
    class GridContainerComponent{
        @Input() data: any;
        @Output() dataChange = new EventEmitter();
    
        //You must trigger this method from GridContainer somehow. E.g. on button click
        updateData() {
            this.data.someCounter++;
            //this row is the most important, and you have to call it manually each time you want to prompt new value to parent. 
            //I.e. in another place you can update 'this.data' but do not update that value in Parent just skipping this line.
            this.dataChange.emit(this.data);
        }
    }
    

    如果你有 2 个兄弟姐妹,那么它仍然是 2 路数据绑定,其中 Parent 充当代理:

    <grid>
        <grid-component [(dataChild1)]="dataParent"></grid-component>
        <grid-container [(dataChild2)]="dataParent"></grid-container>
    </grid>
    

    或者您可以使用服务Sibling Component Communication

    【讨论】:

    • 我想你误解了我的问题。我的问题是用最少的 ts 代码更新的。已经给出了要初始化的 html 部分。
    • 请为GridComponentGridContainer 添加您的模板。你的定义太多了。提供的模板显示&lt;grid&gt;,但它如何与&lt;grid-component&gt;&lt;grid-container&gt; 结合尚不清楚。此外,如果您使用Array,即使没有 2 路数据绑定,它也会在 Parent 和 Child 中更新(请参阅 SuperParent to Parent 关系)。 plnkr.co/edit/VxfkUKGNYaL5QHBxuCR2?p=preview
    【解决方案2】:

    这有点晚了,但如果有人到达这里可能会看到解决方案。我认为最好的解决方案是service,它提供了简单明了的数据传递方式。在您的情况下,孩子应该 subscribeobservable 并且在父组件中,只要您想更新子组件中的数据,就应该使用服务方法来传递数据。下面的例子。也可以看看angular 2 cookbook

    父组件

    export class GridContainer {
       constructor(private GridService: GridService) {  }
       private data: any[] = [];
       private addItem(el) {
          this.data.push(el);
          this.GridService.pushGridData(this.data);
       }
    }
    

    子组件

    export class GridComponent implements OnInit, OnDestroy {
       constructor(private GridService: GridService) {  }
       private data: any[] = [];
       private subscribtion: Subscribtion;
       ngOnInit(): void {
          this.Subscribtion = this.GridService.gridData.subscribe(
             (data) => { this.data = data; }
          )
       }
       ngOnDestroy(): void {
          this.Subscribtion.unsubscribe();
       }
    }
    

    服务

    @Injectable();
    export class GridService {
       constructor() {  }
    
       private gridDataSource = new Subject<any[]>()
    
       gridData = this.gridDataSource.asObservable();
    
       pushGridData(data) {
          this.gridDataSource.next(data);
       }
    }
    

    【讨论】:

      猜你喜欢
      • 2016-12-02
      • 2016-03-01
      • 2019-02-14
      • 1970-01-01
      • 1970-01-01
      • 2021-04-25
      • 2019-02-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多