如何在 Angular 4 中使用 RxJS 将道具正确传递给组件? [英] How to correctly pass props to a component with RxJS in Angular 4?

查看:23
本文介绍了如何在 Angular 4 中使用 RxJS 将道具正确传递给组件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的组件:

@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,就像它被传递给组件一样.

When I change the name in input and then I am pressing save button and this.good is NOT CHANGED good. It is old good, like it was passed to the component.

我开始调试问题.我添加了 onInput 处理程序.我发现当我执行此指令时:this.good.name = $event.target.value; 我在控制台中收到此错误:

I started to debug the problem. I added onInput handler. I found that when I do this instruction: this.good.name = $event.target.value; I get this error in console:

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>

这是我接收此组件数据的方式:

Here is how I receive data for this component:

/*…*/
selectedGood$: Observable<Good>;

constructor(private store: Store<fromRoot.State>) {
  /*…*/
  this.selectedGood$ = store.select(fromRoot.getGoodSelectedEntity);
}

容器组件的完整代码如下:这里.

Here is the full code of container component: here.

思考:我认为问题是因为 Observable 返回了不可变的结构.我不认为这完全是个坏主意,但如何处理呢?

Thoughts: I think the problem is because Observable returns immutable structure. I don’t think it is totally bad idea, but how to handle it?

我试图在那里获得相同的行为:http://plnkr.co/edit/gdxEcSvC0v6JwoLEZDkJ?p=预览.它不会繁殖.我认为这是因为

I am trying to get same behaviour there: http://plnkr.co/edit/gdxEcSvC0v6JwoLEZDkJ?p=preview. It does not reproduce. I think this is because

如何解决我的问题?我不想得到这样的错误.当我按下保存时,我希望 this.good 包含变异的对象.如何实现这一目标?

How to solve my problem? I don’t want to get such error. When I press save I want this.good to contain mutated object. How to achieve this?

推荐答案

您可以在演示文稿组件中创建原始对象的副本,并在保存时发出该副本的值.发出变异对象后,您调度的操作应将其存储为有效负载,并且reducer 应负责将旧对象替换为变异对象.这至少是我在演示组件中使用的方法:)

You could create a copy of the original object in your presentation component and emit the value of that copy onClick of save. After emiting the mutated object, the action that you dispatch should store it as payload and the reducer should take care of replacing the old object with the mutated one. That is at least the approach that I use in my presentation components :)

例如:

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);
  }
}

这篇关于如何在 Angular 4 中使用 RxJS 将道具正确传递给组件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆