У меня есть метод, который возвращает устройства, и я вижу, что он возвращает 2 устройства:
public getDevices(): Observable<Array<Device>> {
return this.state$
.pipe(
map((devices: Array<Device>) => {
return devices
})
);
}
Но если я добавлю фильтр для элементов массива, он вообще не отобразит устройства:
public getDevices(): Observable<Array<Device>> {
return this.state$
.pipe(
map((devices: Array<Device>) => {
return devices
.filter((device: Device) => {
return device != null && device.mute != true
})
}),
);
}
То же самое для жестко закодированного фильтра истинности:
public getDevices(): Observable<Array<Device>> {
return this.state$
.pipe(
map((devices: Array<Device>) => {
return devices
.filter((device: Device) => {
return true
})
}),
);
}
Я также пробовал со следующим, и все равно он не отображает никаких устройств:
public getDevices(): Observable<Array<Device>> {
return this.state$
.pipe(
map((devices: Array<Device>) => {
devices = devices.filter((device: Device) => {
return device != null && device.mute != true
})
return devices;
}),
);
}
Это показывает не пустые массивы в логгере:
public getDevices(): Observable<Array<Device>> {
return this.state$
.pipe(
tap((devices: Array<Device>) => {
console.log(devices);
}),
// map((devices: Array<Device>) => {
// return devices
// .filter((device: Device) => {
// return device != null && device.mute != true
// })
// }),
);
}
Содержимое консоли браузера:
(2) [Device, Device]
0: Device
id: "MidiThroughPort-0"
name: "Midi Through Port-0"
mute: false
midiMessageSubscription: Subscriber {closed: false, _parentOrParents: null, _subscriptions: Array(1), syncErrorValue: null, syncErrorThrown: false, …}
synth: s.default.PolySynth {_context: s.d…t.Context, output: s.d…t.Volume, _volume: s.d…t.Volume, volume: s.d…t.Param, _scheduledEvents: Array(0), …}
keyboard: Piano {_events: {…}, _maxListeners: undefined, type: "Piano", parent: div#keyboard-device-MidiThroughPort-0, width: 500, …}
__proto__: Object
1: Device {id: "VMPKOutput", name: "VMPK Output", mute: false, midiMessageSubscription: Subscriber, synth: s.d…t.PolySynth, …}
length: 2
Но раскомментированный закомментированный код как:
public getDevices(): Observable<Array<Device>> {
return this.state$
.pipe(
tap((devices: Array<Device>) => {
console.log(devices);
}),
map((devices: Array<Device>) => {
return devices
.filter((device: Device) => {
return device != null && device.mute != true
})
}),
);
}
делает регистратор, да тот же самый регистратор, теперь показывает пустой массив: []
Одна очень странная вещь состоит в том, что, когда я комментирую код фильтра, регистратор вызывается только один раз, один раз пустой []
И когда я раскомментирую код фильтра, вышеуказанный регистратор вызывается 5 раз, сначала пустой []
, а затем 4 раза непустой (2) [Device, Device]
Вот как я могу добавить устройство:
public addDevice(device: Device) {
const index = this.getDeviceIndex(device.id);
if (index === -1) {
device.id = this.commonService.normalizeName(device.id);
this.getState().push(device);
}
}
с состоянием:
export class Store<T> {
state$: Observable<T>;
private _state$: BehaviorSubject<T>;
protected constructor(initialState: T) {
this._state$ = new BehaviorSubject(initialState);
this.state$ = this._state$.asObservable();
}
public getState(): T {
return this._state$.getValue();
}
public setState(nextState: T) {
this._state$.next(nextState);
}
}
ОБНОВЛЕНИЕ: Наблюдаемое не было уведомлено любого изменения, когда pu sh другой элемент к его значению массива. Поэтому я создал еще один метод в классе Store
, который перезагружает наблюдаемое:
public reloadState() {
this._state$.next(this._state$.getValue());
}
Я вызываю этот метод после нажатия другого элемента в массиве устройств:
public addDevice(device: Device) {
const index = this.getDeviceIndex(device.id);
if (index === -1) {
device.id = this.commonService.normalizeName(device.id);
this.getState().push(device);
this.reloadState();
}
}