简体   繁体   English

Angular 2 observables:防止组件冒泡的变化

[英]Angular 2 observables: prevent changes in component bubbling up

In my app, I have a UserService that fetches a user object from an API.在我的应用程序中,我有一个从 API 获取用户对象的 UserService。

import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';

@Injectable()
export class UserService {
    constructor() {
        this.userSource.subscribe(user => console.log(user));
    }

    user:any = {
        name: 'Lindsey Buckingham'
    };
    private userSource = new BehaviorSubject<any>(this.user);
    user$ = this.userSource.asObservable();

    // fetch user data from HTTP and call 'next()' on observable
}

Then I have multiple components consuming this service.然后我有多个组件使用此服务。 For example, a profile page:例如,个人资料页面:

import { Component } from '@angular/core';

import { UserService } from '../shared/user.service';

@Component({
    selector: 'profile',
    templateUrl: './profile.component.html'
})
export class ProfileComponent {
    constructor(private userService:UserService) {}

    private user:any = {};

    ngOnInit() {
        this.userService.user$.subscribe((user) => this.user = user);
    }
}

Now the issue I'm having is this: if in my profile component I edit the user object, the change immediately propagates everywhere, so all components immediately receive the updated object.现在我遇到的问题是:如果在我的配置文件组件中编辑用户对象,更改会立即传播到任何地方,因此所有组件都会立即收到更新的对象。 I was under the impression that by subscribing to the stream from the UserService, I would create a local copy and if I wanted to update the user object in my components, I'd use a method on the UserService that calls this.user$.next() and only then the user object in my components would change, as well.我的印象是通过订阅来自 UserService 的流,我会创建一个本地副本,如果我想更新组件中的用户对象,我会在 UserService 上使用一个调用this.user$.next()然后我的组件中的用户对象也会改变。 But, apparently not.但是,显然不是。

Getting the hang of observables, but it seems I'm not quite there yet.掌握 observables 的窍门,但似乎我还没有完全掌握。 Could anyone explain to me where I'm going wrong?谁能向我解释我哪里出错了?

Update:更新:

Creating a local copy of the observed object indeed does do the trick.创建观察对象的本地副本确实可以解决问题。

ngOnInit() {
    this.userService.user$.subscribe((user) => {
        let localUser = _.merge({}, user); 
        this.user = localUser;
    });
}

The observable just passes the object reference along. observable 只是传递对象引用。 If you modify properties of this object, then everyone that has a reference to this same object instance sees this change.如果您修改此对象的属性,则所有引用此同一对象实例的人都会看到此更改。 Only with primitive values copies are sent.仅发送原始值副本。 It's the same as with function calls and actually that exactly what observables do (as any TypeScript or JS code)它与函数调用相同,实际上这正是 observable 所做的(就像任何 TypeScript 或 JS 代码一样)

You need to create a copy yourself if you don't want to work with copies, or you change the code that emits values to create a copy before sending the event.如果您不想使用副本,则需要自己创建一个副本,或者在发送事件之前更改发出值的代码以创建副本。

See also typescript - cloning object另请参阅打字稿 - 克隆对象

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM