Angular 4 - 使用带有RXJS Observable的Object.assign

时间:2017-11-30 04:01:47

标签: angular rxjs observable angular2-observables

我是Observables的新手,仍然试图了解他们的工作方式。

我试图从一个observable中获取一个数组并允许它被更改,但不会影响observable。我以为我能用Object.assign()

做到这一点

流程是:

  1. 从API获取一系列发票。
  2. 将其存储为服务中的BehaviorSubject Observable。
  3. 用户导航至'查看所有发票'屏幕。
  4. 用户点击'编辑'一张发票
  5. 编辑组件加载,订阅Observable,从数组中查找正确的发票,并将其分配给单独的this.invoice对象。
  6. 用户应该能够在不影响可观察的
  7. 的情况下编辑this.invoice

    但不是。 6不起作用。如果用户点击了编辑帐单,对发票进行了更改,则不会将其保存到数据库,而是返回查看发票屏幕并再次单击编辑,更改仍然存在。我希望能够显示原始发票,而不是新编辑的发票。

    在user.service中:

    export class UserService {
      ...
      public invoices: BehaviorSubject<any> = new BehaviorSubject(null);
      ...
      constructor(){
      };
    }
    

    获取发票阵列:

    userLogin() {
      this.commonService.request('login', '', {password: this.password, email: this.email})
        .then((response:any) => {
          ...
          if(response.invoiceData) this.userService.invoices.next(response.invoiceData);
          ...
          }
        })
    }
    

    查看发票组件:

    ngOnInit() {
      this.invoicesSubscription = this.userService.invoices.subscribe((invoices) => {
        if(invoices) {
          this.invoices = invoices;
        }
    
      });
    }
    

    修改发票组件:

    ngOnInit() {
      this.paramsSubscription = this.activatedRoute.params.subscribe((params: Params) => {
        if(params) {
          this.invoicesSubscription = this.userService.invoices.subscribe((invoices) => {
            if(invoices) {
              invoices.forEach((invoice) => {
                if(invoice._id == params.invoiceId) {
                  this.invoice = Object.assign({}, invoice); 
                  console.log(invoice) // This shows changes to the invoice when the screen loads for the second time.
                }
              });
            }
          });
        }
      });
    }
    

    如何在没有影响Observable的更改的情况下编辑this.invoice对象?

2 个答案:

答案 0 :(得分:0)

我使用JSON.parse(JSON.stringify(invoice))代替Object.assign({},invoice)解决了这个问题。在编辑发票组件中。

答案 1 :(得分:0)

Observable只允许您将数据视为流,您可以使用运算符在其中执行很棒的操作。但他们并没有以任何方式“存储”数据 - 他们只看到一个供给观察者的元素列表,将数据转换部分留给消费者。

Object.assign({}, obj)不会对对象执行深度复制。在你的情况下,在this.invoice的级别上进行更改不应该回到位于BehaviorSubject中的原始对象(例如this.invoice.foo = 'bar'),但是如果你只是深入一级,它将(例如this.invoice.items.push('bar')

您需要制作对象的完整副本(搜索,有很多方法可以做到这一点)。您也可以使用Immutable.js来帮助您,但使用它们有点痛苦......(它是一个允许您存储不可变数据的库:如果您想要更改某些部分的数据它,它将为您提供所需更改的对象的全新副本,保留原始文件