如何在 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);
  }
}