All Projects → microstates → ember

microstates / ember

Licence: MIT License
@microstates/ember - Official Microstates bindings for Ember.js

Programming Languages

javascript
184084 projects - #8 most used programming language
HTML
75241 projects
CSS
56736 projects

Projects that are alternatives of or similar to ember

react-store
A library for better state management in react hooks world
Stars: ✭ 34 (-50%)
Mutual labels:  state-management
ember-cli-simditor
Ember component wrapper for simditor editor
Stars: ✭ 16 (-76.47%)
Mutual labels:  ember
k-ramel
State manager for your components apps, the safe and easy way
Stars: ✭ 20 (-70.59%)
Mutual labels:  state-management
ember-website
The emberjs.com website.
Stars: ✭ 61 (-10.29%)
Mutual labels:  ember
ember-eui
Ember Components for Elastic Eui
Stars: ✭ 22 (-67.65%)
Mutual labels:  ember
Nanny-State
simple state management
Stars: ✭ 68 (+0%)
Mutual labels:  state-management
ember-sort-filter-table
A sortable/searchable table addon for ember cli
Stars: ✭ 13 (-80.88%)
Mutual labels:  ember
ember-local-storage-decorator
Decorator for Ember.js to read and persist data in localStorage
Stars: ✭ 13 (-80.88%)
Mutual labels:  ember
ast-builder
Build your ASTs directly from code
Stars: ✭ 18 (-73.53%)
Mutual labels:  ember
fea state machines
A Buffet Of C++17 State Machines
Stars: ✭ 19 (-72.06%)
Mutual labels:  state-machines
november-cli
❄️ Generate a Node.js API for your Ember.js app
Stars: ✭ 51 (-25%)
Mutual labels:  ember
react-stateful-component
Functional stateful React components with sideEffect support
Stars: ✭ 19 (-72.06%)
Mutual labels:  state-management
atom-ember-snippets
Ember.js ES6 snippets for Atom
Stars: ✭ 37 (-45.59%)
Mutual labels:  ember
chat-app-v2
Shorter Chat App Demo
Stars: ✭ 14 (-79.41%)
Mutual labels:  ember
ember-gridstack
Ember components to build drag-and-drop multi-column grids powered by gridstack.js
Stars: ✭ 31 (-54.41%)
Mutual labels:  ember
ember-deep-tracked
Deep auto-tracking for when you just don't care, and want things to work (at the cost of performance in some situtations)
Stars: ✭ 20 (-70.59%)
Mutual labels:  ember
ember-key-manager
A service for (un)binding keyboard up and down events.
Stars: ✭ 39 (-42.65%)
Mutual labels:  ember
state-workflow
State Workflow Management Package For Laravel. Inspired by ROAM Horizon State Management Package.
Stars: ✭ 29 (-57.35%)
Mutual labels:  state-management
pinia-shared-state
🍍 A lightweight plugin to sync your pinia state across browser tabs.
Stars: ✭ 51 (-25%)
Mutual labels:  state-management
eslint-plugin-ember-best-practices
Static analysis tools for enforcing best practices in Ember
Stars: ✭ 77 (+13.24%)
Mutual labels:  ember

@microstates/ember

API Index Live Demo

npm version Ember Observer Score Build Status Greenkeeper badge Chat on Discord

  • Ember.js v3.8 or above
  • Ember CLI v2.13 or above
  • Node.js v8 or above

Why Microstates?

Short explanation, it's going to be the most fun you've had working with state in any framework.

Long explanation, components have values and actions that can be invoked to change these values. We call this state. To change the state of a component, you call an action that calls this.set to change the value. State and its transitions become an inseperable part of the component. Microstates make component state seperable from the component. To learn what makes this seperation possible, checkout How do Microstates work in Ember?

A Microstate is an object that is created from type and value. Type declares what states are created when a microstate is created from this type and how these microstates can be transitioned. Seperating state from the component makes many difficult things easy and fun.

Here are some benefits,

  • Unit testing state becomes trivially easy.
  • Serializing and deserializing complex graphs of state is built in.
  • Never have to use this.set or this.get in a Microstate.
  • Never have to write actions.
  • Write mostly template only components.
  • Make state portable across apps and frameworks.

What is a Microstate?

A microstate is an immmutable object that knows how to derive changed version of itself.

Microstates comes with 6 built-in types: Boolean, Number, String, Array, Object and Any. All other types you create yourself by composing primitive types into data structures that reflect the needs of your UI. You can declare custom types by using ES6 class syntax.

class Person {
  age = Number;
  name = String;
  isEmberiño = Boolean;
}

These custom types can be composed further to create complex graphs of state that match complexity of your component. Microstates handles lazily materializing complex data structures allowing you to represent complex one directional graphs without worrying about penality of materializing state that your component might not be using.

Microstates have simple rules:

  1. Parents have access to their children
  2. Children do not have access to their parents
  3. Transitions are pure and immutable
  4. Derived state can be safely cached

To learn more about Microstates, go to microstates/microstate.js. For a deeper funner introduction to Microstates checkout Charles Lowell's presentation at EmberATX meetup.

How to use Microstates?

@microstates/ember makes it easy to create microstates that cause Ember to re-render when a transition on the microstate is called. You can create a microstate in JavaScript using state macro or in a template using state helper. In both cases, you will get an object that will have transitions that you can invoke. When you call the transition, the state will update accordingly and your change will be reflected.

Here is one of the simplest Microstates you can make.

{{#let (state 10) as |counter|}}
  {{counter.state}}
  <button {{on "click" (noargs counter.increment)}} type="button">Increment</button>
{{/let}}

state helper is polymorphic, meaning that it accepts arguments of different types. Based on the type of data that you pass to you, you will get a microstate with different transitions that you can invoke in your template. For primitive types, you can create a microstate by providing the initial value.

(noargs) helper is something to prevent passing down the event since increment and decrement take an optional value. It looks like this:

import { helper } from '@ember/component/helper';

export default helper(([act]) => {
  return () => {
    return act();
  };
});

For custom type, you can use (type name) helper to resolve the type via Ember's dependency injection system. Here is how we'd use our Person type.

// app/types/person.js
class Person {
  age = Number;
  name = String;
  isEmberino = Boolean;
}
{{#let (state (type "person") initial) as |person|}}
  {{person.name.state}} - {{person.age.state}} {{person.isEmberino.state}}
  <input type="text" onchange={{tval person.name.set}}>
  <button {{on "click" (noargs person.age.increment)}} type="button">Make older</button>
  <button {{on "click" person.isEmberino.toggle}} type="button">Change projects</button>
{{/let}}

How do Microstates work in Ember?

To understand how Microstates work in Ember we must decompose actions into their distict parts. These parts are,

  1. Transition of state
  2. Initiate rerender

Transition of state is done by changing properties on the component with this.set. A rerender is initiated as a side-effect of calling this.set.

Microstates makes these two operations much clearer. Microstates by default are pure. They do not have any side-effects. However, we still need to call this.set when a transition computed the next state to initiate a rerender. Microstates provides a Store mechanism that accepts a callback. We use this callback to invoke this.set to initiate a rerender.

Here is what that would look like if we didn't use the macro that @microstates/ember provides.

import Component from '@glimmer/component';
import { computed } from '@ember/object';
import { create, Store } from '@microstates/ember';

class Person {
  name = String;
  age = Number;
}

let microstate = create(Person, { name: 'Taras' });

export default class PersonManager extends Component {
  @tracked state = Store(microstate, next => this.state = next);
}

Now any transition that you invoke on the state, will automatically create the next state and trigger a re-render. Here is the same component with the macro.

import Component from '@glimmer/component';
import { state } from '@microstates/ember';

class Person {
  name = String;
  age = Number;
}

export default class PersonManager extends Component {
  @state(Person, { name: 'Taras' })
  state;
}

Checkout the demos for examples of how Microstates can be used.

Installation

  • git clone this repository
  • npm install
  • bower install

Running

Running Tests

  • npm test (Runs ember try:testall to test your addon against multiple Ember versions)
  • ember test
  • ember test --server

Building

  • ember build

For more information on using ember-cli, visit http://ember-cli.com/.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].