Store

Store allows you to save and distribute data between components in your application.

import store from 'akili/src/services/store';
console.log(store === Akili.services.store); // true

store is a javascript Proxy object. So you can just change a property of this object anywhere you want, and it will trigger all necessary changes.

store.currentUser = { name: 'Nick' };

When you change a nested property in the store object, the changes will not be transferred. You always need to change the root property.

class FirstComponent extends Akili.Component {
  compiled() {
    setTimeout(() => {
      store.currentUser = { name: 'Alex' });
    }, 2000);
  }
}

class SecondComponent extends Akili.Component {
  compiled() {
    this.store('currentUser', user => this.scope.user = user);
  }
}
<second-component>${ this.user.name }</second-component>

At start, it is Nick. In two seconds it is Alex.

class FirstComponent extends Akili.Component {
  compiled() {
    this.store('currentUserName', 'userInFirst');

    setTimeout(() => {
      this.scope.userInFirst = 'Bill';
    }, 2000);
  }
}

class SecondComponent extends Akili.Component {
  compiled() {
    this.store('currentUserName', 'userInSecond');

    setTimeout(() => {
      this.scope.userInSecond = 'Alex';
    }, 4000);
  }
}
<first-component>${ this.userInFirst }</first-component>
<second-component>${ this.userInSecond }</second-component>

At start, we'll see undefined inside the elements above. In two seconds it will be Bill in both of the components. When userInFirst property is changed, it changes the store property currentUserName, which changes userInSecond property. It's like a double binding. You associate the scope property with the store property. In four seconds it will be the same thing, but in the opposite direction and we can see Alex inside the both elements.

Component.prototype.store(name, handler, options)

  • name string - link name
  • handler string | string[] | function - scope property or a function to link
  • [options] Object - options, for example { callOnStart: false }

If you want to link a nested scope's property, then specify each nested key in the array from left to right.

class FirstComponent extends Akili.Component {
  compiled() {
    this.store('currentUserName', ['user', 'name']); // this.scope.user.name
  }
}

To get any store's property change just pass a callback without the key.

class SecondComponent extends Akili.Component {
  compiled() {
    this.store((val, key) => {
      if(key == 'currentUserName') {
        this.scope.userInSecond = val;
      }
    });
  }
}

The function options are the same as attribute options.

Component.prototype.unstore(name, handler)

  • name string - link name
  • handler string | string[] | function - scope property or a function to unlink