Command Pattern With Angular
Uses a command pattern to create decoupled commands that can be bound to buttons, or menu items.
HTML
<script src="http://code.angularjs.org/1.2.0-rc.3/angular.min.js"></script>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css">
<script src="http://code.angularjs.org/1.2.0-rc.3/angular-route.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.3/js/bootstrap.min.js"></script>
<div data-ng-controller="Ctrl as ctrl" class="container">
<div class="row">
<div class="col-md-6">
<h2>Buttons</h2>
<button type="button" class="btn btn-primary" data-ng-repeat="cmd in ctrl.commands" data-ng-click="cmd.execute({msg:'From Button'})" data-ng-disabled="!cmd.canExecute()">{{cmd.name}}</button>
</div>
<div class="col-md-6">
<h2>Dropmenu</h2>
<div>
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">Dropdown <span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li data-ng-repeat="cmd in ctrl.commands" data-ng-class="{disabled:!cmd.canExecute()}"><a href="" data-ng-click="cmd.execute({msg:'From Dropdown'})">{{cmd.name}}</a>
</li>
</ul>
</div>
</div>
</div>
</div>
JavaScript
var Controllers;
(function (Controllers) {
var Ctrl = function (commandService) {
this.commands = [
commandService.getCommand('Home'),
commandService.getCommand('Toggle Admin'),
commandService.getCommand('Admin')];
};
Ctrl.$inject = ['commandService'];
Controllers.Ctrl = Ctrl;
}(Controllers || (Controllers = {})));
var Services;
(function (Services) {
var CommandExecutor = function ($injector, cmd) {
this.name = cmd.name;
this.cmd = cmd;
this.$injector = $injector;
};
CommandExecutor.prototype.canExecute = function () {
return this.$injector.invoke(this.cmd.canExecute, this.cmd);
};
CommandExecutor.prototype.execute = function (params) {
if(this.canExecute()){
this.$injector.invoke(this.cmd.execute, this.cmd, params);
}
};
CommandExecutor.$inject = ['$injector', 'cmd'];
var CommandService = function ($injector) {
this.$injector = $injector;
this.commands = {};
};
CommandService.prototype.executeCommand = function (commandName, options) {
var cmd = this.getCommand(commandName);
if (cmd.canExecute()) {
cmd.execute(options);
}
};
CommandService.prototype.getCommand = function (commandName) {
return this.commands[commandName];
};
CommandService.prototype.addCommand = function (cmd) {
if (angular.isDefined(cmd)) {
this.commands[cmd.name] = this.$injector.instantiate(CommandExecutor, {
cmd: cmd
});
}
};
CommandService.prototype.createUrl = function (url, params) {
if (typeof params === 'undefined') {
params = {};
}
return url.replace(/\:(\w+)/g, function (match, index) {
return typeof params[index] !== 'undefined' ? params[index] : match;
});
};
CommandService.$inject = ['$injector'];
...