【问题标题】:How can I get my variable to update when its reference does?当它的引用发生时,我怎样才能让我的变量更新?
【发布时间】:2016-07-11 20:13:38
【问题描述】:

我有一个 Angular2 组件,其中一个变量设置为另一个服务中的另一个变量。如果不重新设置变量,我这辈子都无法更新它。

在我的 ngOnInit 组件中,我这样做:

ngOnInit(){
   this.rooms = this.globals.filteredRooms;
}

在我的名为 AppGlobals 的 @injectable 中,我总是在做这样的事情:

applyFilters() {
    this.filteredRooms = this.rooms.filter(r => this.campFilters.includes(r.camp));
}

当 appGlobals 中的 filteredRooms 变量发生变化时,我希望组件中的 rooms 变量随之变化。相反,我需要一次又一次地设置 this.rooms = this.globals.filteredRooms。

我已经尝试了一百万件事,例如尝试(可能失败)创建一个 Observable 并订阅它,尝试(但失败)将我的组件导入 appGlobals 以便我可以告诉组件在需要时更新其引用(在删除导入之前抛出非描述性错误),并查看是否需要执行某种 byRef 规范,以便创建对 globals.filteredRooms 的引用而不是复制它?

如果我需要将其更改为参考,那是如何完成的?如果需要的话,我将如何创建一个 Observable 并订阅它?或者……需要什么?

【问题讨论】:

    标签: typescript angular pass-by-reference observable


    【解决方案1】:

    你不能这样做,这就是正在发生的事情:

    let a = [1, 2];
    console.log(a); // [1, 2]
    
    let b = a;
    console.log(b); // [1, 2]
    
    a = [1, 2, 3];
    
    console.log(a); // [1, 2, 3]
    console.log(b); // [1, 2]
    

    如您所见,当您执行a = b 时,您从a 指向与b 相同的位置(在本例中为[1, 2])。
    但是,当您更改 b 时,您只会更改 b 现在指向的内容,a 仍然指向相同的值。

    为了避免这种情况,您可以为值创建一个容器,例如:

    interface Reference {
        value: number[];
    }
    
    let a = { value: [1, 2] };
    console.log(a.value); // [1, 2]
    
    let b = a;
    console.log(b.value); // [1, 2]
    
    a.value = [1, 2, 3];
    
    console.log(a.value); // [1, 2, 3]
    console.log(b.value); // [1, 2, 3]
    

    您尚未发布声明 filteredRooms 成员的代码部分,因此我无法为您编写确切的解决方案,但可以从我的示例中推断出来。

    如果您需要多次执行类似的操作,您可以拥有一个辅助类:

    class Reference<T> {
        private value: T;
    
        public set(value: T): void {
            this.value = value;
        }
    
        public get(): T {
            return this.value;
        }
    }
    

    【讨论】:

    • 感谢您的深入回复。具有讽刺意味的是,就在被激怒到发布这个问题之后,我回去并设法创建了一个 observable。如果您好奇,我会将其作为答案发布。
    【解决方案2】:

    所以在发布这个问题后,我设法创建了 Observable。具有讽刺意味的是,我在这个问题上花了好几天都没有进展。以防万一它帮助别人:

    在我的 AppGlobals 中:

    @Injectable()
    export class AppGlobals {
    
        private _filteredRooms = new BehaviorSubject(this.rooms);
    
        public filteredRooms = this._filteredRooms.asObservable();
    
        public rooms = [];
    
    
        constructor(private roomSvc: RoomSvc) {
            this.getRooms();
        }
    
        applyFilters() {
            this._filteredRooms.next(this.rooms.filter(r => this.campFilters.includes(r.camp)));
        }
    
        getRooms() {
            this.roomSvc.getRooms()
                .subscribe(r => {
                        this.rooms = r;
                        this._filteredRooms.next(this.rooms);
                    }
                );
        }
    }
    

    注意:你需要从 'rxjs/BehaviorSubject' 导入 BehaviorSubject

    在我的组件内部:

    export class TableComp {
       roomSubs: Subscription;
       rooms: Array<any>;
    constructor(private globals: AppGlobals) { }
    
        ngOnInit() {
    
            this.roomSubs = this.globals.filteredRooms
                .subscribe(r =>
                    this.rooms = r
                );
        }
    }
    

    注意:你需要从 'rxjs/Subscription' 导入订阅

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-20
      • 1970-01-01
      • 2021-05-27
      • 1970-01-01
      • 2012-03-23
      • 1970-01-01
      • 2020-09-13
      • 1970-01-01
      相关资源
      最近更新 更多