8

$setPristine works alright when referenced with $scope but doesn't seem to work with 'controller as syntax'

In View:

<h2>With Controller as syntax</h2>
<div ng-controller="FirstCtrl as first">
    <form name="form1" id="form" novalidate>
        <input name="name" ng-model="first.data.name" placeholder="Name" required/>
        <button class="button" ng-click="first.reset()">Reset</button>
    </form>
    <p>Pristine: {{form1.$pristine}}</p>
    <p> <pre>Errors: {{form.$error | json}}</pre> </p>
</div>
<hr>

<h2>With $scope</h2>
<div ng-controller="SecondCtrl">
    <form name="form1" id="form" novalidate>
        <input name="name" ng-model="data.name" placeholder="Name" required/>
        <button class="button" ng-click="reset()">Reset</button>
    </form>
    <p>Pristine: {{form1.$pristine}}</p>
    <p> <pre>Errors: {{form.$error | json}}</pre> </p>
</div>

In app.js:

var app = angular.module('plunker', []);

app.controller('FirstCtrl', function() {
  'use strict';
  var vm = this;
  vm.data = { "name": ""};

    vm.reset = function() {
      vm.data.name = "";
      vm.form1.$setPristine();
    }
});

app.controller('SecondCtrl', function($scope) {
  'use strict';
  $scope.data = { "name": ""};

    $scope.reset = function() {
      $scope.data.name = "";
      $scope.form1.$setPristine();
    }
});

Here is the plunker: http://plnkr.co/edit/VcgZx3?p=preview

4 Answers 4

6

Even if you use controller as syntax, the form and other attributes are still bound to the scope not to the controller instance so you still have to use $scope.form1.$setPristine(); to set the form's state.

var app = angular.module('my-app', [], function() {})

app.controller('FirstCtrl', function($scope) {
  'use strict';
  var vm = this;
  vm.data = {
    "name": ""
  };

  vm.reset = function() {
    vm.data.name = "";
    $scope.form1.$setPristine();
  }
});

app.controller('SecondCtrl', function($scope) {
  'use strict';
  $scope.data = {
    "name": ""
  };

  $scope.reset = function() {
    $scope.data.name = "";
    $scope.form1.$setPristine();
  }
});
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular.js"></script>

<div ng-app="my-app">
  <h2>With Controller as syntax</h2>
  <div ng-controller="FirstCtrl as first">
    <form name="form1" id="form" novalidate>
      <input name="name" ng-model="first.data.name" placeholder="Name" required/>
      <button class="button" ng-click="first.reset()">Reset</button>
    </form>
    <p>Pristine: {{form1.$pristine}}</p>
    <p> <pre>Errors: {{form.$error | json}}</pre> </p>
</div>
<hr/>

<h2>With $scope</h2>
<div ng-controller="SecondCtrl">
  <form name="form1" id="form" novalidate>
    <input name="name" ng-model="data.name" placeholder="Name" required/>
    <button class="button" ng-click="reset()">Reset</button>
  </form>
  <p>Pristine: {{form1.$pristine}}</p>
  <p> <pre>Errors: {{form.$error | json}}</pre> </p>
</div>
</div>

Sign up to request clarification or add additional context in comments.

2 Comments

What are the other attributes that are still bound to the scope and not to the controller instance?
@shyamalparikh only attributes that you are binding to first in the template or added to this or vm in the controller
3

An alternative to using Arun's suggestion of accessing the form through $scope is simply to ensure the form is accessible through the controller.

To do this all you have to do is change your HTML for the 'controller as' version very slightly. Change the form's name to include the controller object, also change any references to the form from the template to include the controller variable:

   <h2>With Controller as syntax</h2>
<div ng-controller="FirstCtrl as first">
    <form name="first.form1" id="form" novalidate>
        <input name="name" ng-model="first.data.name" placeholder="Name" required/>
        <button class="button" ng-click="first.reset()">Reset</button>
    </form>
    <p>Pristine: {{first.form1.$pristine}}</p>
    <p> <pre>Errors: {{form.$error | json}}</pre> </p>
</div>
<hr>

Your Javascript will now run unchanged.

Comments

3

I think an even easier way to accomplish this is to provide the form controller as a parameter to the reset() function:

…
<button class="button" ng-click="reset(form1)">Reset</button>
…

and change the reset() function slightly, so that it uses the supplied parameter:

$scope.reset = function(form) {
  $scope.data.name = "";
  form.$setPristine();
}

Comments

0

You can use $setPristine without $scope:

  <form ng-submit="$ctrl.save()" name="$ctrl.myForm">

And in your controller:

var $ctrl = this;
 ...   
$ctrl.myForm.$setPristine();
$ctrl.myForm.$setUntouched();

It works for me. (AngularJS v1.5.7)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.