2019-07-29 22:47:55 +05:30
|
|
|
import BaseObservableList from "./BaseObservableList.js";
|
|
|
|
|
|
|
|
export default class MappedList extends BaseObservableList {
|
|
|
|
constructor(sourceList, mapper, updater) {
|
|
|
|
super();
|
|
|
|
this._sourceList = sourceList;
|
|
|
|
this._mapper = mapper;
|
|
|
|
this._updater = updater;
|
|
|
|
this._sourceUnsubscribe = null;
|
|
|
|
this._mappedValues = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
onSubscribeFirst() {
|
|
|
|
this._sourceUnsubscribe = this._sourceList.subscribe(this);
|
|
|
|
this._mappedValues = [];
|
|
|
|
for (const item of this._sourceList) {
|
|
|
|
this._mappedValues.push(this._mapper(item));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
onReset() {
|
|
|
|
this._mappedValues = [];
|
|
|
|
this.emitReset();
|
|
|
|
}
|
|
|
|
|
|
|
|
onAdd(index, value) {
|
|
|
|
const mappedValue = this._mapper(value);
|
|
|
|
this._mappedValues.splice(index, 0, mappedValue);
|
|
|
|
this.emitAdd(index, mappedValue);
|
|
|
|
}
|
|
|
|
|
|
|
|
onUpdate(index, value, params) {
|
|
|
|
const mappedValue = this._mappedValues[index];
|
|
|
|
if (this._updater) {
|
2019-07-29 23:22:28 +05:30
|
|
|
this._updater(mappedValue, params, value);
|
2019-07-29 22:47:55 +05:30
|
|
|
}
|
|
|
|
this.emitUpdate(index, mappedValue, params);
|
|
|
|
}
|
|
|
|
|
|
|
|
onRemove(index) {
|
|
|
|
const mappedValue = this._mappedValues[index];
|
|
|
|
this._mappedValues.splice(index, 1);
|
|
|
|
this.emitRemove(index, mappedValue);
|
|
|
|
}
|
|
|
|
|
|
|
|
onMove(fromIdx, toIdx) {
|
|
|
|
const mappedValue = this._mappedValues[fromIdx];
|
|
|
|
this._mappedValues.splice(fromIdx, 1);
|
|
|
|
this._mappedValues.splice(toIdx, 0, mappedValue);
|
|
|
|
this.emitMove(fromIdx, toIdx, mappedValue);
|
|
|
|
}
|
|
|
|
|
|
|
|
onUnsubscribeLast() {
|
|
|
|
this._sourceUnsubscribe();
|
|
|
|
}
|
|
|
|
|
|
|
|
get length() {
|
|
|
|
return this._mappedValues.length;
|
|
|
|
}
|
|
|
|
|
|
|
|
[Symbol.iterator]() {
|
|
|
|
return this._mappedValues.values();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export async function tests() {
|
|
|
|
class MockList extends BaseObservableList {
|
|
|
|
get length() {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
[Symbol.iterator]() {
|
|
|
|
return [].values();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
test_add(assert) {
|
|
|
|
const source = new MockList();
|
|
|
|
const mapped = new MappedList(source, n => {return {n: n*n};});
|
|
|
|
let fired = false;
|
|
|
|
const unsubscribe = mapped.subscribe({
|
|
|
|
onAdd(idx, value) {
|
|
|
|
fired = true;
|
|
|
|
assert.equal(idx, 0);
|
|
|
|
assert.equal(value.n, 36);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
source.emitAdd(0, 6);
|
|
|
|
assert(fired);
|
|
|
|
unsubscribe();
|
|
|
|
},
|
|
|
|
test_update(assert) {
|
|
|
|
const source = new MockList();
|
|
|
|
const mapped = new MappedList(
|
|
|
|
source,
|
|
|
|
n => {return {n: n*n};},
|
|
|
|
(o, n) => o.m = n*n
|
|
|
|
);
|
|
|
|
let fired = false;
|
|
|
|
const unsubscribe = mapped.subscribe({
|
|
|
|
onAdd() {},
|
|
|
|
onUpdate(idx, value) {
|
|
|
|
fired = true;
|
|
|
|
assert.equal(idx, 0);
|
|
|
|
assert.equal(value.n, 36);
|
|
|
|
assert.equal(value.m, 49);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
source.emitAdd(0, 6);
|
|
|
|
source.emitUpdate(0, 7);
|
|
|
|
assert(fired);
|
|
|
|
unsubscribe();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|