Angular 避免变异可观测源

Angular 避免变异可观测源,angular,rxjs,angular2-observables,mutability,Angular,Rxjs,Angular2 Observables,Mutability,我正在构建一个Angular应用程序,其中我有以下情况:一个组件订阅服务上的Observable值,并使用异步管道呈现数据。它在嵌套的编辑组件中注入值,然后呈现一个反应式表单 我的问题是,似乎从表单中提交一个值会直接改变可观察的源(BehaviorSubject)。有没有办法避免这种情况?代码如下,但名称已更改 data.service.ts: export class DataService { private dataSource = new BehaviorSubject<M

我正在构建一个Angular应用程序,其中我有以下情况:一个组件订阅服务上的
Observable
值,并使用
异步管道
呈现数据。它在嵌套的编辑组件中注入值,然后呈现一个
反应式表单

我的问题是,似乎从表单中提交一个值会直接改变可观察的源(
BehaviorSubject
)。有没有办法避免这种情况?代码如下,但名称已更改

data.service.ts:

export class DataService {
    private dataSource = new BehaviorSubject<MyData[]>(null);
    private data$ = this.dataSource.asObservable();

    getDataObservable(): Observable<MyData> {
        // fetch data from api, subscribe to it
        // and call dataSource.next() on subscription result
    }
    
    update(data: MyData) {
        // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        // dataSource.value IS ALREADY MUTATED HERE
        // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    }
}
export class ListComponent implements OnInit {
    @Input() userId: string;
    data$: Observable<MyData[]>;
    dataInEditing: MyData;

    constructor(private dataService: DataService ) { }

    ngOnInit() {
        this.data$ = this.dataService.getDataObservable();
    }

    onDataSelected(data: MyData): void {
        this.dataInEditing = data;
    }

    onDataEdited(data: MyData): void {
        this.dataService.update(data);
        this.dataInEditing = null;
    }
}
<div *ngIf="data$ | async as data; else loading">
    <data-table</data-table> <!--inputs/outputs ommited-->
    
    <data-edit
        *ngIf="!!dataInEditing "
        [data]="dataInEditing "
        (dataChangedEvent)="onDataEdited($event)"></data-edit>
</div>
<ng-template #loading>Loading...</ng-template>
导出类数据服务{
私有数据源=新行为主体(null);
私有数据$=this.dataSource.asObservable();
getDataObservable():可观察{
//从api获取数据,订阅它
//并对订阅结果调用dataSource.next()
}
更新(数据:MyData){
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//dataSource.value在此已发生变异
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
}
}
list.component.ts:

export class DataService {
    private dataSource = new BehaviorSubject<MyData[]>(null);
    private data$ = this.dataSource.asObservable();

    getDataObservable(): Observable<MyData> {
        // fetch data from api, subscribe to it
        // and call dataSource.next() on subscription result
    }
    
    update(data: MyData) {
        // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        // dataSource.value IS ALREADY MUTATED HERE
        // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    }
}
export class ListComponent implements OnInit {
    @Input() userId: string;
    data$: Observable<MyData[]>;
    dataInEditing: MyData;

    constructor(private dataService: DataService ) { }

    ngOnInit() {
        this.data$ = this.dataService.getDataObservable();
    }

    onDataSelected(data: MyData): void {
        this.dataInEditing = data;
    }

    onDataEdited(data: MyData): void {
        this.dataService.update(data);
        this.dataInEditing = null;
    }
}
<div *ngIf="data$ | async as data; else loading">
    <data-table</data-table> <!--inputs/outputs ommited-->
    
    <data-edit
        *ngIf="!!dataInEditing "
        [data]="dataInEditing "
        (dataChangedEvent)="onDataEdited($event)"></data-edit>
</div>
<ng-template #loading>Loading...</ng-template>
导出类ListComponent实现OnInit{
@Input()userId:string;
数据$:可观察;
数据编辑:MyData;
构造函数(私有数据服务:数据服务){}
恩戈尼尼特(){
this.data$=this.dataService.getDataObservable();
}
onDataSelected(数据:MyData):无效{
this.dataInEditing=数据;
}
OnDataEdit(数据:MyData):无效{
this.dataService.update(数据);
this.dataInEditing=null;
}
}
list.component.html:

export class DataService {
    private dataSource = new BehaviorSubject<MyData[]>(null);
    private data$ = this.dataSource.asObservable();

    getDataObservable(): Observable<MyData> {
        // fetch data from api, subscribe to it
        // and call dataSource.next() on subscription result
    }
    
    update(data: MyData) {
        // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        // dataSource.value IS ALREADY MUTATED HERE
        // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    }
}
export class ListComponent implements OnInit {
    @Input() userId: string;
    data$: Observable<MyData[]>;
    dataInEditing: MyData;

    constructor(private dataService: DataService ) { }

    ngOnInit() {
        this.data$ = this.dataService.getDataObservable();
    }

    onDataSelected(data: MyData): void {
        this.dataInEditing = data;
    }

    onDataEdited(data: MyData): void {
        this.dataService.update(data);
        this.dataInEditing = null;
    }
}
<div *ngIf="data$ | async as data; else loading">
    <data-table</data-table> <!--inputs/outputs ommited-->
    
    <data-edit
        *ngIf="!!dataInEditing "
        [data]="dataInEditing "
        (dataChangedEvent)="onDataEdited($event)"></data-edit>
</div>
<ng-template #loading>Loading...</ng-template>


事实上,BehaviorSubject为您提供了确切的项,而不是副本。你不应该改变它的内容。您可以按照建议在贴图操作符中使用扩展操作符。