-
Notifications
You must be signed in to change notification settings - Fork 25
/
component.ts
76 lines (63 loc) · 2.43 KB
/
component.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import * as React from 'react'
import { Link } from './link'
export type LinksCache< S, X extends keyof S> = {
[ K in X ] : Link< S[ K ] >
}
export interface DataBindingSource< S >{
linkAt< K extends keyof S>( key : K ) : Link< S[ K ] >
linkAll<K extends keyof S>( ...keys : K[] ) : LinksCache< S, K >
$at< K extends keyof S>( key : K ) : Link< S[ K ] >
state$<K extends keyof S>( ...keys : K[] ) : LinksCache< S, K >
}
export abstract class LinkedComponent< P, S > extends React.Component< P, S > implements DataBindingSource< S > {
links : LinksCache< S, keyof S > = null;
// @deprecated use `this.$at( key )`
linkAt<K extends keyof S>( key : K ) : Link<S[K]>{
return this.$at( key );
}
// Get the link to the state member with the given key.
$at<K extends keyof S>( key : K ) : Link<S[K]>{
const value = this.state[ key ],
cache = this.links || ( this.links = {} as any ),
cached = cache[ key ];
return cached && cached.value === value ?
cached :
cache[ key ] = new StateLink( this, key, value );
}
// @deprecated use `this.state$()`
linkAll<K extends keyof S>( ...keys : K[] ) : LinksCache< S, K >
linkAll(){
return this.state$.apply( this, arguments );
}
/**
* Get the object with links to the elements of the component's state.
* const state$ = this.state$();
*
* Get the links to the given list of state elements.
* const state$ = this.state$( 'a', 'b', 'c' );
*/
state$<K extends keyof S>( ...keys : K[] ) : LinksCache< S, K >;
state$( ...args : ( keyof S )[] ){
const { state } = this,
cache = this.links || ( this.links = <any>{} ),
keys = args.length ? args : <( keyof S )[]>Object.keys( state );
for( let key of keys ){
const value = state[ key ],
cached = cache[ key ];
if( !cached || cached.value !== value ) {
cache[ key ] = new StateLink( this, key, value );
}
}
return cache;
}
}
export class StateLink< P, S, K extends keyof S > extends Link< S[ K ] > {
constructor( public component : LinkedComponent< P, S >, public key : K, value : S[ K ] ){
super( value );
}
set( x : S[ K ] ) : void {
const attrs = <Pick<S, K>> {};
attrs[ this.key ] = x;
this.component.setState( attrs );
}
}