如何在 Angular 4 中使用 RxJS 正确地将 props 传递给组件?
How to correctly pass props to a component with RxJS in Angular 4?
这是我的组件:
@Component({
selector: 'bc-goods-detail',
template: `
<span>good id: {{good?.id}}</span>
<input [value]="good?.name" (input)="onInput($event)" />
<button (click)="onClick()">Save</button>
`,
styles: []
})
export class GoodsDetailComponent {
@Input() good: Good;
@Output() save = new EventEmitter<Good>();
onClick() {
this.save.emit(this.good);
}
onInput ($event) {
this.good.name = $event.target.value;
}
}
当我更改输入中的名称然后按下保存按钮时,this.good
未更改很好。它是旧的 good
,就像它被传递给组件一样。
我开始调试问题。我添加了 onInput
处理程序。我发现当我执行此指令时:this.good.name = $event.target.value;
我在控制台中收到此错误:
ERROR TypeError: Cannot assign to read only property 'name' of object '#<Object>'
at GoodsDetailComponent.webpackJsonp.435.GoodsDetailComponent.onInput (goods-detail.ts:24)
组件的用法如下:
<bc-goods-detail
[good]="selectedGood$ | async"
(save)="onSave($event)"
></bc-goods-detail>
以下是我接收此组件数据的方式:
/*…*/
selectedGood$: Observable<Good>;
constructor(private store: Store<fromRoot.State>) {
/*…*/
this.selectedGood$ = store.select(fromRoot.getGoodSelectedEntity);
}
这里是容器组件的完整代码:here.
思考:我认为问题是因为Observable returns 不可变结构。我不认为这完全是个坏主意,但是如何处理呢?
我试图在那里获得相同的行为:http://plnkr.co/edit/gdxEcSvC0v6JwoLEZDkJ?p=preview。它不会重现。我认为这是因为
如何解决我的问题?我不想得到这样的错误。当我按下保存时,我希望 this.good
包含变异的对象。如何实现?
您可以在演示组件中创建原始对象的副本,并在单击保存时发出该副本的值。发出变异对象后,您分派的操作应将其存储为有效负载,而 reducer 应负责将旧对象替换为变异对象。这至少是我在演示组件中使用的方法:)
例如:
export class GoodsDetailComponent {
private _original: Good;
goodClone: Good; // use this inside of the component template
@Input('good')
get good(){return this.goodClone;}
set good(value: Good){
this.goodClone= //generate a clone of the object
this._original = value;
}
@Output()
save = new EventEmitter<Good>();
onClick() {
this.save.emit(this.goodClone);
}
}
这是我的组件:
@Component({
selector: 'bc-goods-detail',
template: `
<span>good id: {{good?.id}}</span>
<input [value]="good?.name" (input)="onInput($event)" />
<button (click)="onClick()">Save</button>
`,
styles: []
})
export class GoodsDetailComponent {
@Input() good: Good;
@Output() save = new EventEmitter<Good>();
onClick() {
this.save.emit(this.good);
}
onInput ($event) {
this.good.name = $event.target.value;
}
}
当我更改输入中的名称然后按下保存按钮时,this.good
未更改很好。它是旧的 good
,就像它被传递给组件一样。
我开始调试问题。我添加了 onInput
处理程序。我发现当我执行此指令时:this.good.name = $event.target.value;
我在控制台中收到此错误:
ERROR TypeError: Cannot assign to read only property 'name' of object '#<Object>'
at GoodsDetailComponent.webpackJsonp.435.GoodsDetailComponent.onInput (goods-detail.ts:24)
组件的用法如下:
<bc-goods-detail
[good]="selectedGood$ | async"
(save)="onSave($event)"
></bc-goods-detail>
以下是我接收此组件数据的方式:
/*…*/
selectedGood$: Observable<Good>;
constructor(private store: Store<fromRoot.State>) {
/*…*/
this.selectedGood$ = store.select(fromRoot.getGoodSelectedEntity);
}
这里是容器组件的完整代码:here.
思考:我认为问题是因为Observable returns 不可变结构。我不认为这完全是个坏主意,但是如何处理呢?
我试图在那里获得相同的行为:http://plnkr.co/edit/gdxEcSvC0v6JwoLEZDkJ?p=preview。它不会重现。我认为这是因为
如何解决我的问题?我不想得到这样的错误。当我按下保存时,我希望 this.good
包含变异的对象。如何实现?
您可以在演示组件中创建原始对象的副本,并在单击保存时发出该副本的值。发出变异对象后,您分派的操作应将其存储为有效负载,而 reducer 应负责将旧对象替换为变异对象。这至少是我在演示组件中使用的方法:)
例如:
export class GoodsDetailComponent {
private _original: Good;
goodClone: Good; // use this inside of the component template
@Input('good')
get good(){return this.goodClone;}
set good(value: Good){
this.goodClone= //generate a clone of the object
this._original = value;
}
@Output()
save = new EventEmitter<Good>();
onClick() {
this.save.emit(this.goodClone);
}
}