ng-computed
Computed properties for AngularJS, à la Knockout JS.
Features include automatic dependency management, promise unrapping and (optional) batched watches.
bower install ng-computed
Summary
ng-computed
lets you write computed properties without worrying
about which values to register a $watch
on and when.
$scope.string = "hello";
$scope.$computed('computedValue', function() {
return $scope.$eval('string') + " world!";
});
In this case, $scope.computedValue
will take on the value "hello
world!"
, while also reacting to changes to $scope.string
.
Example
As an example, this is a simple translation of the KnockoutJS computed observable example:
angular.module("example", ["ngComputed", "ng"])
.controller("ExampleController", function($scope, $computed, $trackedEval) {
$scope.$computed = $computed;
$scope.$eval = $trackedEval;
$scope.firstName = "George";
$scope.surname = "Clooney";
$scope.$computed("fullName", function() {
return $scope.$eval("firstName") + " " + $scope.$eval("surname");
});
});
<html ng-app="example">
...
<div ng-controller="ExampleController">
<div>
<input ng-model="firstName">
<input ng-model="surname">
</div>
<div>Hello, {{fullName}}</div>
</div>
...
</html>
To do this in plain AngularJS would require us to manage our watches explicitly:
angular.module("example", ["ng"])
.controller("ExampleController", function($scope) {
$scope.firstName = "George";
$scope.surname = "Clooney";
$scope.$watch("firstName", function(firstName) {
$scope.fullName = firstName + " " + $scope.surname;
});
$scope.$watch("surname", function(surname) {
$scope.fullName = $scope.firstName + " " + surname;
});
});
ng-computed
will do the work of managing watches for you. See
this example to see it in action.
Setup
At the top level we can add our functions to the root scope, even going so far as to replace the functions there:
angular.module('app', ['ngComputed', 'ng'])
.run(['$rootScope', '$trackedEval', '$computed', function($rootScope, $trackedEval, $computed) {
// we have to use the prototype, otherwise isolate scopes miss out
angular.extend($rootScope.constructor.prototype, {
$eval: $trackedEval,
$computed: $computed
});
}]);
For the majority of the documentation we will assume this setup, although you can also bind to different names on the scope prototype, or bind them on any sub-scope.
Documentation
See /docs/complete.org for our current documentation.