JSFiddle - React, Tailwind, and code Playground
HTML
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script>
<p><b>AngularJS lazyModel directive</b><br/>
Original model gets updated only when "save" clicked</p>
<div ng-app="app" ng-controller="Ctrl">
<span>Username: <strong>{{user.name}}</strong></span>
<button ng-click="formVisible=true" ng-show="!formVisible">edit</button>
<form ng-submit="formVisible=false" ng-show="formVisible">
<input type="text" lazy-model="user.name">
<button type="submit">save</button>
<button type="reset" ng-click="formVisible=false">cancel</button>
</form>
</div>
CSS
div[ng-app] { margin: 50px; }
JavaScript
var app = angular.module("app", []);
app.controller('Ctrl', function($scope) {
$scope.user = {
name: 'vitalets'
};
});
// == lazyModel directive ==
app.directive('lazyModel', function($parse, $compile) {
return {
restrict: 'A',
require: '^form',
scope: true,
compile: function compile(elem, attr) {
// getter and setter for original model
var ngModelGet = $parse(attr.lazyModel);
var ngModelSet = ngModelGet.assign;
// set ng-model to buffer in isolate scope
elem.attr('ng-model', 'buffer');
// remove lazy-model attribute to exclude recursion
elem.removeAttr("lazy-model");
return function postLink(scope, elem, attr) {
// initialize buffer value as copy of original model
scope.buffer = ngModelGet(scope.$parent);
// compile element with ng-model directive poining to buffer value
$compile(elem)(scope);
// bind form submit to write back final value from buffer
var form = elem.parent();
while(form[0].tagName !== 'FORM') {
form = form.parent();
}
form.bind('submit', function() {
scope.$apply(function() {
ngModelSet(scope.$parent, scope.buffer);
});
});
form.bind('reset', function(e) {
e.preventDefault();
scope.$apply(function() {
scope.buffer = ngModelGet(scope.$parent);
});
});
};
}
};
});