MappedList.findAndUpdate
This commit is contained in:
parent
ce7147e463
commit
a5d5c55835
1 changed files with 77 additions and 2 deletions
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
Copyright 2020 Bruno Windels <bruno@windels.cloud>
|
||||
Copyright 2021 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -17,11 +18,12 @@ limitations under the License.
|
|||
import {BaseObservableList} from "./BaseObservableList.js";
|
||||
|
||||
export class MappedList extends BaseObservableList {
|
||||
constructor(sourceList, mapper, updater) {
|
||||
constructor(sourceList, mapper, updater, removeCallback) {
|
||||
super();
|
||||
this._sourceList = sourceList;
|
||||
this._mapper = mapper;
|
||||
this._updater = updater;
|
||||
this._removeCallback = removeCallback;
|
||||
this._sourceUnsubscribe = null;
|
||||
this._mappedValues = null;
|
||||
}
|
||||
|
@ -56,6 +58,9 @@ export class MappedList extends BaseObservableList {
|
|||
onRemove(index) {
|
||||
const mappedValue = this._mappedValues[index];
|
||||
this._mappedValues.splice(index, 1);
|
||||
if (this._removeCallback) {
|
||||
this._removeCallback(mappedValue);
|
||||
}
|
||||
this.emitRemove(index, mappedValue);
|
||||
}
|
||||
|
||||
|
@ -70,6 +75,21 @@ export class MappedList extends BaseObservableList {
|
|||
this._sourceUnsubscribe();
|
||||
}
|
||||
|
||||
findAndUpdate(predicate, updater) {
|
||||
const index = this._mappedValues.findIndex(predicate);
|
||||
if (index !== -1) {
|
||||
const mappedValue = this._mappedValues[index];
|
||||
// allow bailing out of sending an emit if updater determined its not needed
|
||||
const params = updater(mappedValue);
|
||||
if (params !== false) {
|
||||
this.emitUpdate(index, mappedValue, params);
|
||||
}
|
||||
// found
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
get length() {
|
||||
return this._mappedValues.length;
|
||||
}
|
||||
|
@ -79,6 +99,8 @@ export class MappedList extends BaseObservableList {
|
|||
}
|
||||
}
|
||||
|
||||
import {ObservableArray} from "./ObservableArray.js";
|
||||
|
||||
export async function tests() {
|
||||
class MockList extends BaseObservableList {
|
||||
get length() {
|
||||
|
@ -126,6 +148,59 @@ export async function tests() {
|
|||
source.emitUpdate(0, 7);
|
||||
assert(fired);
|
||||
unsubscribe();
|
||||
}
|
||||
},
|
||||
"test findAndUpdate not found": assert => {
|
||||
const source = new ObservableArray([1, 3, 4]);
|
||||
const mapped = new MappedList(
|
||||
source,
|
||||
n => {return n*n;}
|
||||
);
|
||||
mapped.subscribe({
|
||||
onUpdate() { assert.fail(); }
|
||||
});
|
||||
assert.equal(mapped.findAndUpdate(
|
||||
n => n === 100,
|
||||
() => assert.fail()
|
||||
), false);
|
||||
},
|
||||
"test findAndUpdate found but updater bails out of update": assert => {
|
||||
const source = new ObservableArray([1, 3, 4]);
|
||||
const mapped = new MappedList(
|
||||
source,
|
||||
n => {return n*n;}
|
||||
);
|
||||
mapped.subscribe({
|
||||
onUpdate() { assert.fail(); }
|
||||
});
|
||||
let fired = false;
|
||||
assert.equal(mapped.findAndUpdate(
|
||||
n => n === 9,
|
||||
n => {
|
||||
assert.equal(n, 9);
|
||||
fired = true;
|
||||
return false;
|
||||
}
|
||||
), true);
|
||||
assert.equal(fired, true);
|
||||
},
|
||||
"test findAndUpdate emits update": assert => {
|
||||
const source = new ObservableArray([1, 3, 4]);
|
||||
const mapped = new MappedList(
|
||||
source,
|
||||
n => {return n*n;}
|
||||
);
|
||||
let fired = false;
|
||||
mapped.subscribe({
|
||||
onUpdate(idx, n, params) {
|
||||
assert.equal(idx, 1);
|
||||
assert.equal(n, 9);
|
||||
assert.equal(params, "param");
|
||||
fired = true;
|
||||
}
|
||||
});
|
||||
assert.equal(mapped.findAndUpdate(n => n === 9, () => "param"), true);
|
||||
assert.equal(fired, true);
|
||||
},
|
||||
|
||||
};
|
||||
}
|
||||
|
|
Reference in a new issue