0.3.0 • Published 7 years ago

flexmixin v0.3.0

Weekly downloads
2
License
MIT
Repository
github
Last release
7 years ago

Flexmixin

This is a very simple library, which was made mostly for testing purposes. It works for very limited tested use cases, but if you should use a more mature library for production. This https://github.com/justinfagnani/mixwith.js for instance is a robust library, one from which I took a lot of inspiration and solutions.

Installation

npm install flexmixin

Functionality

This library exposes two ways of doing things. to().add() and mix().with().

to().add()

Let's say you wrote your own Observable interface and its implementation, e.g.:

class Observable {
  
  on() { throw "On not implemented"; }
  off() { throw "Off not implemented"; }
  notify() { throw "Notify not implemented"; }

}

class ObservableImpl extends Observable {

  constructor() {
    super();
    this.listeners = {};
  }

  on(event, fn) {
    this.listeners[event] = fn;
  }

  off(event) {
    this.listeners[event] = undefined;
  }

  notify(event) {
    this.listeners[event]();
  }
}

And now you want another class to have the functionality of your ObservableImpl. Well, you can extend your class, but JavaScript does not support multiple inheritance. You can use composition, add functions that delegate to an instance of ObservableImpl. You can also use mixins. With this library you can do this:

import { to } from "flexmixin";

class Person {}

class PersonImpl extends to(Person).add(ObservableImpl) {
  
  constructor(name) {
    super();
    this.name = name;
  }
  
  changeName(name) {
    this.name = name;
    this.notify("name_change");
  }
}

let person = new PersonImpl("Frist");
person.on("name_change", () => console.log("Name changed!"));
person.changeName("Second"); // will print "Name changed!"
console.log(person instanceof Person); //true
console.log(person instanceof ObservableImpl); //false

Internally, to(superclass).add(...classes) will create new instances of classes and assign their properties (fields) to superclass. Ideally, you wouldn't want to use classes which need parameters with this method.

mix().with()

Now this is a different way of achieving similar functionality. You can define your own mixin like so:

let ObservableMixin = (superclass) => class extends superclass {
  
  constructor() {
    super();
    this.listeners = {};
  }

  on(event, fn) {
    this.listeners[event] = fn;
  }

  off(event) {
    this.listeners[event] = undefined;
  }

  notify(event) {
    this.listeners[event]();
  }  
}

And use it to add functionality to your classes.

import { mix } from "flexmixin";

class View {}

class PersonView extends mix(View).with(ObservableMixin) {
  
  constructor() {
    super();
    this.person = {};
  }
      
  setPerson(person) {
    this.person = person;
    this.notify("person_change");
  }
}

let personView = new PersonView("Frist");
personView.on("person_change", () => console.log("Person changed!"));
personView.setPerson(new Person()); // will print "Person changed!"
console.log(person instanceof PersonView); //true
console.log(person instanceof ObservableImpl); //false

You can also use defined mixins (almost) effortlessly in place of regular classes and instantiate them in code.

let Mixin = ObservableMixin(Object); // class expression
let observable = new Mixin(); //instantiate
observable.on("notify", () => console.log("Notified!"));
observable.notify("notify"); //prints "Notified!"
0.3.0

7 years ago

0.2.1

7 years ago

0.2.0

7 years ago

0.1.0

7 years ago

0.0.3

7 years ago

0.0.2

7 years ago

0.0.1

7 years ago