Basically, in angular if something is not declarative, you make a directive.
.directive('shadow', function() {
return {
scope: {
target: '=shadow'
},
link: function(scope, el, att) {
scope[att.shadow] = angular.copy(scope.target);
scope.commit = function() {
scope.target = scope[att.shadow];
};
}
};
Then:
<div shadow="data">
<input ng-model="data">
<button ng-click="commit()">save</button>
</div>
So data
inside the shadow
directive will be a copy of the original data
.
And it will be copied back to the original when the button is clicked.
And here is working example: jsbin
I've not tested it beyond this example, so it may not work in other cases, but I think it gives an idea of the possibilites.
Edit:
Another example with an object instead of a string, and several fields in the form (an additional angular.copy
is required here): jsbin
Edit2, angular versions 1.2.x
As per this change,
the input
inside the directive is not accessing the isolated scope anymore. One alternative is creating a non-isolated child scope (scope:true
), to hold the copy of the data and accessing the parent scope for saving it.
So for later versions of angular, this is the same approach as before slightly modified to do the trick:
.directive('shadow', function() {
return {
scope: true,
link: function(scope, el, att) {
scope[att.shadow] = angular.copy(scope[att.shadow]);
scope.commit = function() {
scope.$parent[att.shadow] = angular.copy(scope[att.shadow]);
};
}
};
});
Example: jsbin
Note that the problem with using $parent
, is that it may break if eventually there is another scope in the middle.