dartscale

A modular clientside framework for complex applications.


License
MIT

Documentation

dartscale Build Status

Is a modular clientside framework for complex applications.

its basicly a slightly altered version of the JavaScript Libray

Philosophy

In traditional MVC Apps, the controllers often have a tight coupling to each other: everyone is accessing each others properties, calls their methods and so on...

This can cause serious problems: if modules depend on each other, the app quickly falls apart if we modify or remove them. Thus quickly leading to an unmaintainable codebase, even in an structured language like Dart where the tools can detect changes in Method/Classnames and signatures.

The Module theory aims to untangle that tight coupling: by seperating the parts of the application into autarc modules and isolating them so they cant actually reference each other, we're getting a rock solid application structure.

This philosophy is well explained in this Talk from Nicholas Zakas

Features

no subclassing required

Your module classes don't have to subclass any specific framework class. Only a specific constructor and 2 additional methods are necessary.

easy plugin system

The Sandbox object can be easily extended with custom plugins, utilizing Darts noSuchMethod

Usage

Creating a Core

The Core is the central context for the application, hosting the modules and messagebus.

var core = new Core();

Subclassing from Core

Another option to use the core would be to subclass it

class Application extends Core {
  main () {
    this.register(() => new MyModule(), 'Mymodule');
    this.start('MyModule');
  }
}

main () {
  new Application().main();
}

Defining a module

Modules can be unique or reusable parts of your application and host any functionality you want.
You're not creating them by yourself, the module instances are managed by the Core.

Also their lifecycle is managed by the Core: start is the point where you kick off their functionality, stop is where you shut them down.

The init method is passed a sandbox object through which the module has access to the messagebus (mediator) and the plugins which were registered in the sandbox.

class MyModule {

  Sandbox _sandbox;
  Element _contentEl;

  start(options, sandbox) {
    _sandbox = sandbox;

    _contentEl = new Element.html(['<div class="module-mymodule">',
      '<h1>No message yet</h1>',
    '</div>'].join(''));

    _sandbox.mediator('app', 'greeting').stream.listen((data) {
      _contentEl.query('h1').text = sandbox.CP.composeGreeting(data);
    });
  }

  stop() {
    _contentEl.remove();
  }
}

Registering a module

You simply pass a constrcutor function to the register method.

var core = new Core();
core.register(() => new MyModule(), 'MyModule');

Add sandbox plugins

Sandbox plugins can be pretty much anything, from pure functions to entire class instances.

class ComposerPlugin {
  composeGreeting(name) {
    return "Hello Mr./Ms ${name}!";  
  }
}

var sandbox = new Sandbox(new Mediator());
sandbox.registerPlugin("CP", new ComposerPlugin());

print(sandbox.CP.composeGreeting("Marcelus Wallace"))

Start everything up

By starting a single or multiple modules, you start your app.

//pass null to second argument to use the modules name as its Id
core.start('MyModule', options: {
  "container": query(".container")
});

//or

core.startAll({
  "container": query(".container")
});

core.mediator('app', 'greeting').add('Stranger');