$ watch only three times

I use a smart table ( http://lorenzofox3.imtqy.com/smart-table-website/ ) for AngularJS, and I created a flag called isReset that will cause the table to reload. This is because I have a directive that monitors the flag, and the update will start when isReset is installed, and after it is updated, it will turn off the flag again.

My problem is that when I set the flag, it runs for the first time, but after observing the flag’s behavior it seems like it never returns to false. I tried to manually set the flag to false, but the next time around $ watch it didn't even work. My code is as follows, it would be great if you could help me shed some light on the problem. The strangest thing is, I have another place where I use it the same way, and it works as intended.

Js

$scope.resetFilter = function() { $scope.timestampFilter = ""; $scope.levelFilter = ""; }; $scope.getAPIServerLogs = function (tableState) { $scope.isLoading = true; ServerLog.get({ "serverType": "API", "timestampFilter": $scope.timestampFilter, "levelFilter": $scope.levelFilter, "offset": tableState.pagination.start, "limit": tableState.pagination.number, "sortField": tableState.sort.predicate, "order": tableState.sort.reverse ? "desc" : "asc" }, function (response) { $scope.isLoading = false; $scope.serverlogs = response.data; $scope.displayedserverlog = [].concat($scope.serverlogs); tableState.pagination.numberOfPages = response.pages; }); }; 

Directive

 directives.directive('stReset', function () { return { require: '^stTable', replace: false, scope: {stReset: "=stReset"}, link: function (scope, element, attr, ctrl) { scope.$watch("stReset", function () { if (scope.stReset) { // reset scope value var tableState = ctrl.tableState(); tableState.pagination.start = 0; tableState.sort.prediate = {}; tableState.search = {}; ctrl.pipe(); scope.stReset = false; } }, true); } }; 

HTML

 <table st-table="displayedserverlog" st-safe-src="serverlogs" st-pipe="getAPIServerLogs" class="table table-striped table-hover logtable"> <thead st-reset="isReset"> <tr> <th st-sort-default="reverse" st-sort="timestamp" width="11%">Timestamp</th> <th st-sort="logger" width="30%">logger</th> <th st-sort="level" width="3%">Level</th> <th st-sort="thread" width="11%">Thread</th> <th st-sort="message" width="45%">Message</th> </tr> </thead> <tbody ng-repeat="serverlog in serverlogs"> <tr ng-click="click(serverlog)" ng-class="{'tr-active':serverlog.isClicked, 'pointer danger':serverlog.exception}"> <td>{{serverlog.timestamp | date: 'yyyy-MMM-dd hh:mm:ss'}}</td> <td>{{serverlog.logger}}</td> <td>{{serverlog.level}}</td> <td>{{serverlog.thread}}</td> <td>{{serverlog.message}}</td> </tr> <tr ng-show="serverlog.isClicked"> <td colspan="6"> <div class="row"> <div class="col-md-12"> <div>{{serverlog.exception}}</div> <pre><div ng-repeat="trace in serverlog.stacktrace track by $index" class="stacktrace">{{trace}} </div></pre> </div> </div> </td> </tr> </tbody> <tfoot ng-hide="isLoading"> <tr> <td colspan="10" class="text-center"> <div st-pagination="" st-items-by-page="50"></div> </td> </tr> </tfoot> 

+5
source share
3 answers

This plunker simulates your problem: http://plnkr.co/edit/c8crhe9ZR44GQBJ2sqm6?p=preview (look at the console)

  scope.$watch("flag", function(neww, old){ count ++; console.log("inWatch " + count + ": " + neww + ', ' + old); if (scope.flag === true) { scope.flag = false; } }); 

Setting the flag to false in $ watch basically means that it will always be false (because: you change the value β†’ $ watch running β†’ at the end of the function sets the value to false β†’ value false)

0
source

I have found a solution. Still not sure why it works, but I added

 scope.$parent.$parent.isReset = false; 

to the end of the directive, it works as it is intended. However, replacing existing

scope.stReset = false;

broke another place, I use this directive. Until I do both. In the future, when I'm smarter in AngularJS, I will look at this issue again. Hope this helps someone in the future, so they don’t spend three days trying to figure it out like me.

0
source

try it.

 var watcher = $scope.$watch('someScope', function(newValue, oldValue){ if(newValue === 'yourValue') { watcher(); // stop this watch } }); 
0
source

All Articles