问题
I have two nested components: grid-container
and grid-component
.
In grid-container
, the grid-component
is initialized as follows:
<grid [title]="'This is the grid title'" [data]="data"></grid>
Data is initialized. Using events, the updated data
in grid-component
can be obtained in grid-container
. Its obvious until here for me. However, what should we typically do in angular 2 to update data
in the nested component (grid-component
in this case) from the container component (grid-container
)?
More specifically, (or as an illustration) I need a function that adds an item in container component (grid-container
) which will be applied in data
in grid-component
ps: its not two-way data binding as in this question which also didn't work for this problem.
EDIT:
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.
}
}
回答1:
It's a bit late, but maybe if someone get here will see solution. I think the best solution for this is service
which provide easy and clear way to pass data. In your case the child's should subscribe
an observable
and in parent component you should use service method to pass data whenever you want to update data in child's components. Example below. Also look at the angular 2 cookbook
Parent component
export class GridContainer {
constructor(private GridService: GridService) { }
private data: any[] = [];
private addItem(el) {
this.data.push(el);
this.GridService.pushGridData(this.data);
}
}
Child Component
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();
}
}
Service
@Injectable();
export class GridService {
constructor() { }
private gridDataSource = new Subject<any[]>()
gridData = this.gridDataSource.asObservable();
pushGridData(data) {
this.gridDataSource.next(data);
}
}
回答2:
Your question is not clear. Please provide example of your HTML. If you have Parent-Child relation, then it is 2 way databinding.
@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);
}
}
If you have 2 Siblings, then it is still 2 way databinding where Parent serves as Proxy:
<grid>
<grid-component [(dataChild1)]="dataParent"></grid-component>
<grid-container [(dataChild2)]="dataParent"></grid-container>
</grid>
Or you can use Service Sibling Component Communication
来源:https://stackoverflow.com/questions/41124292/angular2-way-to-update-data-in-nested-component-from-parent-component