AngularJS - Using ampersand bindings to communicate between controllers & directives
by vacationlabs
HTML
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.min.js"></script>
<div ng-app="MyModule" ng-controller="MyController">
<script type="text/ng-template" id="in-place-edit.html">
<div>
<div ng-show="ui.mode=='view'">{{ model }} <a href="" ng-click="ui.mode='edit'">edit</a></div>
<div ng-show="ui.mode=='edit'">
<input type="text" ng-model="new_model" />
<button type="button" ng-click="save()">Save</button>
<button type="button" ng-click="ui.mode='view'">Cancel</button>
</div>
</script>
<p>Edit this field and hit save (mocks a successful save)</p>
<div in-place-edit="name" on-save="save_name(new_value)"></div>
<hr/>
<p>Edit this field and hit save (mocks a failed save)</p>
<div in-place-edit="phone" on-save="save_phone(new_value)"></div>
</div>
JavaScript
var mod = angular.module('MyModule', []);
mod.controller('MyController', ['$scope', '$window', function($scope, $window) {
$scope.name="Vacation Labs";
$scope.phone="99999 12345";
$scope.save_name = function(new_value) {
$window.alert('Asssume that we make an AJAX request to save the name, which succeeds');
$scope.name=new_value;
return true;
};
$scope.save_phone = function(new_value) {
$window.alert('Assume that we make an AJAX request to save the phone, which fails due to some validation error. Which means we DONT update the model');
return false;
};
}]);
mod.directive('inPlaceEdit', function() {
return {
'restrict' : 'A',
'scope' : {
'model' : '=inPlaceEdit',
'on_save' : '&onSave'
},
// This can probably be abstracted out into a templateUrl
'templateUrl' : 'in-place-edit.html',
'replace' : true,
'link' : function(scope, element, attrs) {
scope.ui = {'mode' : 'view'};
scope.save = function() {
scope.on_save({'new_value' : scope.new_model});
scope.ui.mode='view';
}
scope.$watch('model', function(m) {
scope.new_model = angular.copy(m);
});
}
}
});