Garden simulator
HTML
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.js"></script>
<div ng-app="myApp">
<h1>
The garden
</h1>
<div ng-controller="myCtrl">
<table>
<tr ng-repeat="row in world.grid track by $index">
<td ng-repeat="cell in row track by $index">
<img src="http://www.freepngimg.com/download/grass/5-grass-png-image-green-grass-png-picture.png" height="{{cell.grass}}" width="10">
<img src="http://www.outworldz.com/SeamlessTextures/master/Grass%20textures,CC0/3td_Africa_Grass01.png" height="{{cell.thorns}}" width="10">
</td>
</tr>
</table>
<button ng-click="cycle(rows)">
cycle
</button>
<button ng-click="cycle(world, {rain: 0})">
drought
</button>
</div>
JavaScript
(function(ng, _) {
'use strict';
var
lodashModule = ng.module('angular-lodash', []),
utilsModule = ng.module('angular-lodash/utils', []),
filtersModule = ng.module('angular-lodash/filters', []);
// begin custom _
function propGetterFactory(prop) {
return function(obj) {
return obj[prop];
};
}
_._ = _;
// Shiv "min", "max" ,"sortedIndex" to accept property predicate.
_.each(['min', 'max', 'sortedIndex'], function(fnName) {
_[fnName] = _.wrap(_[fnName], function(fn) {
var args = _.toArray(arguments).slice(1);
if (_.isString(args[2])) {
// for "sortedIndex", transmuting str to property getter
args[2] = propGetterFactory(args[2]);
} else if (_.isString(args[1])) {
// for "min" or "max", transmuting str to property getter
args[1] = propGetterFactory(args[1]);
}
return fn.apply(_, args);
});
});
// Shiv "filter", "reject" to angular's built-in,
// and reserve lodash's feature(works on obj).
ng.injector(['ng']).invoke(['$filter', function($filter) {
_.filter = _.select = _.wrap($filter('filter'), function(filter, obj, exp) {
if (!(_.isArray(obj))) {
obj = _.toArray(obj);
}
return filter(obj, exp);
});
_.reject = function(obj, exp) {
// use angular built-in negated predicate
if (_.isString(exp)) {
return _.filter(obj, '!' + exp);
}
var diff = _.bind(_.difference, _, obj);
return diff(_.filter(obj, exp));
};
}]);
// end custom _
// begin register angular-lodash/utils
_.each(_.methods(_), function(methodName) {
function register($rootScope) {
$rootScope[methodName] = _.bind(_[methodName], _);
}
_.each([
lodashModule,
utilsModule,
ng.module('angular-lodash/utils/' + methodName, [])
], function(module) {
module.run(['$rootScope', register]);
});
});
// end register angular-lodash/utils
// begin...