2013-11-30
My Little Machines Part 2

Goal: Create AngularJS directives to support My Little Machines ™

My goal here is to create a directive that implements the MachineController from my previous post, but that also manages the creation of any DOM elements and provides for the ability to invoke Angular expressions from within the machine.

I have created a separate machine.js file to contain this directive code.

Experiment A - Create a machine

Let’s try it out by defining a <machine> below, and hooking up the same types of buttons and indicators as in the previous article.

Reset Step Resume


Here is the code for the above:

<machine ptr="myMachineA" style="background-color:#777777;">

<h6 style="color:#11DD11;" class="pull-left">Time: {{ myMachineA.getMachineTime() }}</h6>
<h6 style="color:#11DD11;" class="pull-right">State: {{ myMachineA.getMachineState() }}</h6>
<br/>

<hr style="height:25px; width:{{ 25 * (myMachineA.getMachineTime() + 1) }}px; background-color:{{ myMachineA.isRunning() ? 'green' : 'red' }};"/>

<button ng-click="myMachineA.resetMachine()">Reset</button>

<button ng-disabled="!myMachineA.isRunning()" ng-click="myMachineA.stepMachine()">Step</button>
<button ng-disabled="!myMachineA.isRunning() || myMachineA.isPaused()" ng-click="myMachineA.resumeMachine()">Resume</button>

</machine>

Experiment B - Create two independent machines

In order to make sure that the machine directive can be embedded more than once per page, I use an attribute ptr on the directive to specify a name to uniquely identify a machine and its state. So in the example above, I used ptr="myMachineA"; in the example below, I’ll present a slightly differently styled machine, that has a ptr="myMachineB". Verify that clicking buttons in the machine above has no effect on the machine below.

Note that using the same ptr for two machines will have unspecified behavior, so be careful.

Reset Step Resume


Here is the code for the above:

<machine ptr="myMachineB" style="background-color:#DDDDDD;">

<div style="background-color:#111111;">
<hr style="height:55px; width:{{ 25 * (myMachineB.getMachineTime() + 1) }}px; background-color:{{ myMachineB.isRunning() ? 'lightgreen' : 'red' }};"/>

<h6 style="color:#11DD11;" class="pull-left">Time: {{ myMachineB.getMachineTime() }}</h6>
<h6 style="color:#11DD11;" class="pull-right">State: {{ myMachineB.getMachineState() }}</h6>
<br/>

</div>

<button ng-click="myMachineB.resetMachine()">Reset</button>

<button ng-disabled="!myMachineB.isRunning()" ng-click="myMachineB.stepMachine()">Step</button>
<button ng-disabled="!myMachineB.isRunning() || myMachineB.isPaused()" ng-click="myMachineB.resumeMachine()">Resume</button>

</machine>