new Slot()
A Slot could be created in 2 methods:
new Slot(value)
this will make a data slot
new Slot(valueFunc, followings)
this will make a follower slot, where followings is an Array. if the element (say following) in observables is a:
Slot
if following changed, follower will be re-evaludated by executing valueFunc, following.val() will be used as valueFunc's argument. its new value is the return value of valueFunc, and change will be propogated to follower's followers.
not Slot
when follower is re-evaluated, following will be used as valueFunc's argument directly.
and valueFunc will accept 2 parameters:
- the current value of observables
mutation process context, it has two keys:
roots - the mutation process roots, namely, those changed by clients (api caller) directly
involved - the observed involed in this mutation process
the context is very useful if the evaluation function needs to return value according to which of its followings mutated
let's see two example:
const $$following = Slot(1); const $$follower = Slot((following, n) => following + n, [$$following, 2]); console.log($$follower.val()); // output 3, since n is always 2 $$following.inc(); console.log($$follower.val()); // output 4, since n is always 2
const $$a = Slot(1).tag('a'); const $$b = Slot(([a]) => a + 1, [$$a]).tag('b'); const $$c = Slot(2).tag('c'); const $$d = Slot(function ([a, b], {roots, involved}) { console.log(roots.map(it => it.tag())); // output [a] console.log(involved.map(it => it.tag())); // output [b] return a + b; }); // a is root of mutation proccess, and c is not changed in this mutation proccess $$a.inc();
Methods
change(proc) → {Slot}
add a change handler
!!!Warning, this is a very dangerous operation if you modify slots in change handler, consider the following scenario:
let $$s1 = Slot(1);
let $$s2 = $$s1.makeFollower(it => it * 2);
let $$s3 = $$s1.makeFollower(it => it * 3);
$$s2.change(function () {
$$s1.val(3); // forever loop
));
$$s1.val(2);
as a thumb of rule, don't set value for followings in change handler
Parameters:
Name | Type | Description |
---|---|---|
proc |
function | it will be invoked when slot is mutated in one mutation process the same order as it is added, it accepts the following parameters:
for example, you could refresh the UI, when ever the final view changed |
Returns:
this
- Type
- Slot
concat(arr) → {Slot}
concat the Slot's value with an array
Parameters:
Name | Type | Description |
---|---|---|
arr |
array |
- Source:
Returns:
this
- Type
- Slot
dec(cnt) → {Slot}
decrement the slot's value, the slot's value should be of type number
Parameters:
Name | Type | Description |
---|---|---|
cnt |
number | the value to be deremented, default is 1 |
- Source:
Returns:
this
- Type
- Slot
divide(n) → {Slot}
divides the slot's value by n, the slot's value should be of type number
Parameters:
Name | Type | Description |
---|---|---|
n |
number | the divisor |
- Source:
Returns:
this
- Type
- Slot
filter(fn) → {Slot}
filter the Slot's value with a function
Parameters:
Name | Type | Description |
---|---|---|
fn |
function |
- Source:
Returns:
this
- Type
- Slot
Example
const $$s = $$([1, 2, 3, 4]);
console.log($$s.filter(it => it % 2 == 0).val()); // 2, 4
follow(valueFunc, followings) → {Slot}
unfollow all the followings if any and follow the new followings using the new valueFunc, this method will mutate the following graph.
!!NOTE this method will not re-evaluate the slot and starts the mutation process at once, so remember to call touch at last if you want to start a mutaion process
Parameters:
Name | Type | Description |
---|---|---|
valueFunc |
function | |
followings |
array | please see Slot's constructor |
Returns:
this
- Type
- Slot
fork(func)
make a follower slot of me. this following has only one followings it is me.
Parameters:
Name | Type | Description |
---|---|---|
func |
function | the evaluation function |
Examples
const $$s1 = Slot(1);
const $$s2 = $$s1.fork(n => n + 1);
is equivalent to:
const $$s1 = Slot(1);
const $$s2 = Slot(([n]) => n + 1, [$$s1]);
inc(cnt) → {Slot}
increment the slot's value, the slot's value should be of type number
Parameters:
Name | Type | Description |
---|---|---|
cnt |
number | the value to be added, default is 1 |
- Source:
Returns:
this
- Type
- Slot
isTopmost() → {boolean}
test if slot observes others
Returns:
true if it observes others, else false
- Type
- boolean
map(fn) → {Slot}
map the Slot's value with a function
Parameters:
Name | Type | Description |
---|---|---|
fn |
function |
- Source:
Returns:
this
- Type
- Slot
Example
const $$s = $$([1, 2, 3]);
console.log($$s.map(it => it * 2).val()); // 2, 4, 6
mod(n) → {Slot}
get remainder the slot's value, the slot's value should be of type number
Parameters:
Name | Type | Description |
---|---|---|
n |
number | the divisor |
- Source:
Returns:
this
- Type
- Slot
Example
const $$s = $$(17).mod(7);
console.log($$s.val()); // output 3
multiply(n) → {Slot}
multiply the slot's value by n, the slot's value should be of type number
Parameters:
Name | Type | Description |
---|---|---|
n |
number | the multiplier |
- Source:
Returns:
this
- Type
- Slot
mutateWith(func, args) → {Slot}
apply the function to me
Parameters:
Name | Type | Description |
---|---|---|
func |
function | the mutation function |
args |
array | the extra arguments provided to func, default is [] |
Returns:
this
- Type
- Slot
Examples
const $$s = Slot(1);
$$s.mutateWith(function (s, n) {
return s + n;
}, [2]);
console.log($$s.val()); // output 3
is equivalent to
const $$s = Slot(1);
$$s.val(function (s, n) { return s + n; }($$s.val(), 2));
mutationTester(tester)
set a handler to Slot to test if slot is mutated, here is an example:
Parameters:
Name | Type | Description |
---|---|---|
tester |
function | a handler to test if slot is changed in one mutation process, if a slot finds all its dependents are unmutation, the mutation process stops from it. A propriate tester will improve the performance dramatically sometimes. it access slot as this and slot's new value and old value as arguments, and return true if slot is changed in mutation process, else false. |
Example
let $$s1 = Slot(true);
let $$s2 = Slot(false);
let $$s3 = Slot((s1, s2) => s1 && s2, [$$s1, $$s2])
.mutationTester((oldV, newV) => oldV != newV);
$$s4 = $$s3.makeFollower((s3) => !s3)
.change(function () {
console.log('s4 changed!');
});
// $$s2 will be changed to true, but $$s3 is not changed,
// neither $$s4 will be changed
$$s2.toggle();
off() → {Slot}
make the Slot's value to be false
- Source:
Returns:
this
- Type
- Slot
offChange()
remove the change handler
- Source:
- See:
omit() → {Slot}
omit the keys
- Source:
Returns:
this
- Type
- Slot
Example
const $$s = $$({ name: 'Tom', color: 'Blue' });
$$s.omit(['color']);
console.log($$s.val(); // { name: 'Tom' }
on() → {Slot}
make the Slot's value to be true
- Source:
Returns:
this
- Type
- Slot
override(targetSlot) → {Slot}
detach the target slot from its followings, and let its followers connect me(this), just as if slot has been eliminated after the detachment. this method is very useful if you want to change the dependent graph
!!NOTE this method will not re-evaluate the slot and starts the mutation process at once, so remember to call touch at last if you want to start a mutaion process
Parameters:
Name | Type | Description |
---|---|---|
targetSlot |
Slot |
Returns:
this
- Type
- Slot
patch(obj) → {Slot}
patch the object value
Parameters:
Name | Type | Description |
---|---|---|
obj |
object | object used to patch me |
- Source:
Returns:
this
- Type
- Slot
Example
const $$s = $$({ name: 'Tom', color: 'Blue' });
$$s.patch({ name: 'Jerry', species: 'Mouse' });
console.log($$s.val()); // { name: 'Jerry', species: 'Mouse', colur: 'Blue' }
pop() → {Slot}
push the Slot's value
- Source:
Returns:
this
- Type
- Slot
Example
const $$s = $$([1, 2, 3]);
console.log($$s.pop().val()); // 1, 2
push() → {Slot}
push the Slot's value
- Source:
Returns:
this
- Type
- Slot
Example
const $$s = $$([1, 2, 3]);
console.log($$s.push(4).val()); // 1, 2, 3, 4
removeFollowing(idx)
this is the shortcut of replaceFollowing(idx)
!!NOTE this method will not re-evaluate the slot and starts the mutation process at once, so remember to call touch at last if you want to start a mutaion process
Parameters:
Name | Type | Description |
---|---|---|
idx |
number | the index of |
replaceFollowing(idx, following) → {Slot}
replaceFollowing, why not just re-follow, since follow is a quite expensive operation, while replaceFollowing only affect the replaced one
!!NOTE this method will not re-evaluate the slot and starts the mutation process at once, so remember to call touch at last if you want to start a mutaion process
Parameters:
Name | Type | Description |
---|---|---|
idx |
the index of following |
|
following |
a slot or any object, if not provided, the "idx"th following will not be followed anymore. |
Returns:
this
- Type
- Slot
reverse() → {Slot}
reverse the Slot's value
- Source:
Returns:
this
- Type
- Slot
Example
const $$s = $$([1, 2, 3]);
console.log($$s.pop().val()); // [3, 2, 1]
set() → {Slot}
set the property of Slot's value
- Source:
Returns:
this
- Type
- Slot
Example
const $$s = $$({ name: 'Tom', color: 'Red' });
$$s.set('color', 'Blue');
console.log($$s.val(); // { name: 'Tom', color: 'Red' }
setIn() → {Slot}
set the deep property of Slot's value
- Source:
Returns:
this
- Type
- Slot
Examples
const $$s = $$({ name: 'Tom' });
$$s.setIn(['friend', 'name'], 'Jerry');
console.log($$s.val(); // { name: 'Tom', frien: { 'name': 'Red'} }
const s = slot({});
s.setIn(['a', 1], 'abc'); // { a: [, 'abc'] }
setV(newV)
set the slot's value, and starts a mutation process
Parameters:
Name | Type | Description |
---|---|---|
newV |
any | the new value of slot, |
shift() → {Slot}
shift the Slot's value
- Source:
Returns:
this
- Type
- Slot
Example
const $$s = $$([1, 2, 3, 4]);
console.log($$s.shift().val()); // 2, 3, 4
shrink() → {Slot}
shrink to a data slot with value val
Returns:
this
- Type
- Slot
slice() → {Slot}
slice the Slot's value
- Source:
Returns:
this
- Type
- Slot
Example
const $$s = $$([1, 2, 3, 4]);
console.log($$s.slice(1, 2).val()); // [2]
tag(v) → {string|Slot}
Set/get tag of slot, useful when debugging.
Parameters:
Name | Type | Description |
---|---|---|
v |
string | undefined | if is string, set the tag of slot and return this, else return the tag |
Returns:
- Type
- string | Slot
Example
// set tag will return this
const $$s = Slot('foo').tag('bar');
console.log($$s.tag()); // output bar
toggle() → {Slot}
toggle the Slot's value
- Source:
Returns:
this
- Type
- Slot
touch(propogate, context, callChangeCbs) → {boolean}
touch a slot, that means, re-evaluate the slot's value forcely, and starts mutation process and call change callbacks if neccessary. usually, you don't need call this method, only when you need to mutate the following graph (like override, replaceFollowing, follow)
Parameters:
Name | Type | Description |
---|---|---|
propogate |
if starts a mutation process, default is true |
|
context |
if null, the touched slot is served as roots, default is null |
|
callChangeCbs |
if call change callbacks, default is true |
- Source:
- See:
Returns:
- return true if this Slot is mutated, else false
- Type
- boolean
unshift() → {Slot}
shift the Slot's value
- Source:
Returns:
this
- Type
- Slot
Example
const $$s = $$([2, 3, 4]);
console.log($$s.unshift(1).val()); // 1, 2, 3, 4
val() → {any|Slot}
get or set the value, if no argument is given, get the current value of Slot, otherwise, set the value of Slot, the mutation process starts, and returns this
Returns:
- Type
- any | Slot