防止在init上触发$ watchCollection

时间:2017-02-20 15:29:01

标签: javascript angularjs

我有“$scope.postits”数组,我想在每次更改时都保留它。因此,我将$scope.$watchCollection放在此元素上以侦听更改并保存数据。问题是$ watch在页面加载时被触发3次(我的测试数组有3个条目)。 怎么预防?我的代码出了什么问题?

视图:

<div ng-controller="postitController as postit" class="container animate-bottom">
    <h2>Post-it !</h2>
    <div class="btn-container">
        <button ng-click="addPostit()" id="add-new-note" class="btn btn-primary">Add postit</button>
    </div>
    <div class="post-it-container">
        <div ng-repeat="postit in postits" class="postit">
            <a ng-click="removePostit(postit)" class="delete-postit glyphicon glyphicon-remove"></a>
            <textarea ng-model="postit.content" ></textarea>
        </div>
        <div ng-if="postits.length==0" class="no-postit well lead">Keep cool and have a beer there's no postit here !</div>
    </div>  
</div>

JS控制器:

app.controller('postitController', function($scope, $http, $timeout) {
    $scope.postitsLoaded = false;
    var storage = {
        endpoint: "localhost/backend/ws.php",
        get: function() {
            $http({
                method: 'GET',
                url: this.endpoint
            }).then(function successCallback(response) {
                $scope.postits = response.data;
                $scope.postitsLoaded = true;
                console.log("init done") ;
            }, function errorCallback(response) {
                console.log(response);
            });
        },
        save: function () {
            $http({
                method: 'POST',
                url: this.endpoint,
                data: "postits="+ angular.toJson($scope.postits),
                headers: {'Content-Type': 'application/x-www-form-urlencoded'}
            }).then(function successCallback(response) {
                console.log(response);
            }, function errorCallback(response) {
                console.log(response);
                alert("error");
            });
        }
    }
    $scope.$watchCollection("postits", function (newValue, oldValue) {
        if(newValue === oldValue || !$scope.postitsLoaded){
            console.log("return") ;
            return;
        }   
        console.log("watch triggered") ;
        storage.save();
    });
    $scope.addPostit = function() {
        $scope.postits.push({id:100,content:"foobar"});
        storage.save();
    };
    $scope.removePostit = function(postit) {
        $scope.postits.splice($scope.postits.indexOf(postit), 1) ; 
        storage.save();
    };
    storage.get();
});

1 个答案:

答案 0 :(得分:1)

这最终使用$ watch并将第三个参数设置为true:

    $scope.$watch("postits", function (newValue, oldValue) {
    //this prevent $watch to be triggered on init 
    if(newValue === oldValue || oldValue === undefined  ){
        console.log("return") ;
        return;
    }   
    console.log("watch triggered") ;
    console.log(oldValue);
    console.log(newValue);
    storage.save();
},true);

使用该解决方案不需要使用任何标志。