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 a 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 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 a key.

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

The function options is 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