title: Is there a pattern for dealing with "Cancel" in AngularJS modal dialogs?
body: <p>Note: This is not about showing a modal dialog with AngularJS, that topic has plenty of questions and answers!</p>
  
  <p>This question is about how to react to both OK and Cancel within a modal dialog on a page. Let's say you've got a scope with just one variable in it:</p>
  
  <pre><code>$scope.description = "Oh, how I love porcupines..."
  </code></pre>
  
  <p>If I provide you with a modal dialog on the page and use ng-model="description" within that dialog, all of the changes you make are actually made in real time to the description itself as you type. That's bad, because then how do you cancel out of that dialog?</p>
  
  <p>There's this question that says to do what I explain below. The accepted answer for it is the same "solution" I came up with: <a href="https://stackoverflow.com/questions/12792077/angularjs-data-bound-modal-save-changes-only-when-save-is-clicked-or-forge">AngularJS: Data-bound modal - save changes only when &quot;Save&quot; is clicked, or forget changes if &quot;Cancel&quot; is clicked</a></p>
  
  <p>I can see how to do it if clicking the button to bring up a modal goes back to a function in the back and that creates a temporary copy of the relevant data for the modal and then pops up the modal. Then "OK" (or "Save" or whatever) could copy the temporary values to the actual model values.</p>
  
  <p>main.js (excerpt):</p>
  
  <pre><code>$scope.descriptionUncommitted = $scope.description;
  
  $scope.commitChanges = function () {
    $scope.description = $scope.descriptionUncommitted;
  }
  </code></pre>
  
  <p>main.html (excerpt):</p>
  
  <pre><code>&lt;input type="text" ng-model="descriptionUncommitted"/&gt;
  
  &lt;button ng-click="commitChanges()"&gt;Save&lt;/button&gt;
  </code></pre>
  
  <p>The problem with that is <b>it's not declarative</b>! In fact, it's nothing like AngularJS anywhere else. It's almost as though we need an ng-model-uncommitted="description" where they could make all the changes they want but they only get committed when we trigger with another declaration. Is there such a thing in a plugin somewhere or is AngularJS itself adding it?</p>
  
  <p><b>Edit: It seems that an example of a different way of doing it might be in order.</b></p>
  
  <p>main.js:</p>
  
  <pre><code>$scope.filename = "panorama.jpg";
  $scope.description = "A panorama of the mountains.";
  
  $scope.persist = function () { // Some function to hit a back end service. };
  </code></pre>
  
  <p>main.html:</p>
  
  <pre><code>&lt;form&gt;
    &lt;input type="text" ng-model-uncommitted="filename"/&gt;
    &lt;input type="text" ng-model-uncommitted="description"/&gt;
  
    &lt;button ng-commit ng-click="persist()"&gt;Save&lt;/button&gt;
    &lt;button ng-discard&gt;Cancel&lt;/button&gt;
  &lt;/form&gt;
  </code></pre>
  
  <p>I stuck a form tag around it because I don't know how you would group the items so it was clear it was all part of the same "transaction" (for lack of a better word). But there would need to be some way that this could all happen automatically and the cloned copies of the model variables are used for initial values, used for input and updated automatically, validated, etc. and then finally discarded or copied to the same value that initially was used to create them if the user decides to commit.</p>
  
  <p>Isn't something like this easier than code in the controller to do that work over and over again for 20 modals in a big website? Or am I nuts?</p>