I have an Angular2 component with a variable set to another variable in another service. I can't for the life of me get it to update without re-setting the variable.
In my component inside ngOnInit I do:
ngOnInit(){
this.rooms = this.globals.filteredRooms;
}
In my @injectable called AppGlobals I'm always doing stuff like this:
applyFilters() {
this.filteredRooms = this.rooms.filter(r => this.campFilters.includes(r.camp));
}
When the filteredRooms variable in appGlobals changes, I want the rooms variable in my component to change with it. Instead I need to set this.rooms = this.globals.filteredRooms again and again.
I've tried a million things such as attempting (probably failing) to create an Observable and subscribe to it, attempting (and failing) to import my component to appGlobals so I can tell the component to update its reference when needed (throws non-descript errors until import is removed), and seeing if I need to do some kind of byRef specification so I'm creating a reference to globals.filteredRooms instead of perhaps copying it?
If what I need is to change it to a reference, how is that done? How would I create an Observable and subscribe to it if that's what's needed? Or... What is needed?
答案 0 :(得分:1)
You can't do that, and here's what's happening:
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]
As you can see, when you do a = b
you point from a
to the same place as b
does (in this case [1, 2]
).
But when you change b
you only change what b
now points to, a
still points to the same value.
In order to avoid this you can have a container for the value, something like:
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]
You haven't posted the part of your code where you declare the filteredRooms
member so I can't write an exact solution for you, but it's deducible from my example.
You can have a helper class if you need to do something like this more than once:
class Reference<T> {
private value: T;
public set(value: T): void {
this.value = value;
}
public get(): T {
return this.value;
}
}
答案 1 :(得分:0)
So just after posting this question I managed to create the Observable. Ironic because I spent days on this issue with no progress. Just in case it helps someone else:
Inside my 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);
}
);
}
}
Note: You need to import BehaviorSubject from 'rxjs/BehaviorSubject'
And inside my component:
export class TableComp {
roomSubs: Subscription;
rooms: Array<any>;
constructor(private globals: AppGlobals) { }
ngOnInit() {
this.roomSubs = this.globals.filteredRooms
.subscribe(r =>
this.rooms = r
);
}
}
Note: you need to import Subscription from 'rxjs/Subscription'