0

I got this example from the W3Schools tutorial on AngularJS. I made a small change from binding the value of the checkbox span to using an expression. I figured that the todo list wouldn't update any more. But it still does. What causes the ng-repeat to fire just because I have added a todo item?

http://plnkr.co/edit/Kojz2ODWDS8dFDNzjYR5?p=preview

<!DOCTYPE html>
<html>
  <script src= "http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>

  <body ng-app="myApp" ng-controller="todoCtrl">

    <h2>My Todo List</h2>

    <form ng-submit="todoAdd()">
        <input type="text" ng-model="todoInput" size="50" placeholder="Add New">
        <input type="submit" value="Add New">
    </form>

    <br>

    <div ng-repeat="x in todoList">
        <input type="checkbox" ng-model="x.done"> <span>{{x.todoText}}</span>
    </div>

    <p><button ng-click="remove()">Remove marked</button></p>

    <script>
    var app = angular.module('myApp', []); 
    app.controller('todoCtrl', function($scope) {
        $scope.todoList = [{todoText:'Clean House', done:false}];

        $scope.todoAdd = function() {

            $scope.todoList.push({todoText:$scope.todoInput, done:false});
            $scope.todoInput = "";
        };

        $scope.remove = function() {
            var oldList = $scope.todoList;
            $scope.todoList = [];
            angular.forEach(oldList, function(x) {
                if (!x.done) $scope.todoList.push(x);
            });
        };
    });
    </script>

  </body>
</html>
dirkk
  • 6,160
  • 5
  • 33
  • 51
abalter
  • 9,663
  • 17
  • 90
  • 145
  • 1
    Short answer is there are internal watches on scope variables used in the view. Changes prompt new digests internally – charlietfl Aug 04 '15 at 16:48
  • How appropriate -- on my list is to read through the links I just bookmarked about watch and digest ;) – abalter Aug 04 '15 at 17:32
  • I accepted the answer below, but you deserve bonus points for pointing out the internal watch. – abalter Aug 04 '15 at 17:34

1 Answers1

1

Clicking the Add New Button submits the corresponding form and by using ng-submit="todoAdd()" it will call this function. This in turn adds an entry to the todoList in your scope. As this array has been modified the angular digest cycle is triggered and the list is updated.

Some suggestions for your questions: First of all, you mean W3Schools, not the W3C (which is a standardization organization and normally is not doing tutorials, which is why I got curios - Also, you will find lots of reasons why not to use W3Schools when goolgin around or looking at meta). Also, if you compare to some other code, you should include it or at least link to it.

I found it by googling and it seems your only change is using <span>{{x.todoText}}</span> instead of <span ng-bind="x.todoText"></span>. There really is no difference in terms of the digest cycle here. The only difference is that by using {{}} it might at first be rendered as curly brackets in the browser window, before the variable is actually replaced. Thus, it is usually better to use ng-bind.

dirkk
  • 6,160
  • 5
  • 33
  • 51
  • nothing wrong with using `{{}}` expressions. Last point doesn't make sense. – charlietfl Aug 04 '15 at 17:37
  • @charlietfl I didn't say that there is anything wrong with it. However, it has some drawbacks - For an extended discussion see here: http://stackoverflow.com/questions/16125872/why-ng-bind-is-better-than-in-angular – dirkk Aug 04 '15 at 17:44
  • never had a single problem in 3 years of using angular if you use `ng-cloak`. Your suggestion is simply opinion based – charlietfl Aug 04 '15 at 17:46
  • @charlietfl **If** you use `ng-cloak` it is not an issue. That is why I wrote _might_. It is not an opinion that using the bracket notation it will first be rendered without replacing the brackets, that **is** a fact. That's all I am saying. – dirkk Aug 04 '15 at 17:49