简体   繁体   中英

AngularJs watch for all in ng-init

I initialize some variables of an AngularJS controller on the server side using ng-init

/* in my server side View */
<div ng-controller="myController" ng-init="myFoo=@myFoo;myBar=@myBar">...</div>

/* in the myApp.js */
app.Controller("myController", function(){
  // wait until myFoo and myBar are initialized, 
  // once defined, perform other tasks

  $scope.$watch("myFoo", function(n,o){}); //?
  $scope.$watch("myBar", function(n,o){}); //?

  // other actions, depending on myFoo and myBar
  for(i=0; i<myFoo; i++) { console.log(myBar); }
});

I need to ensure that when angularjs reaches the for cycle myFoo and myBar variables are already initialized.

Is there a way of doing it (without using strange things like magic=1500 $timeout(magic) )?

Here is a CodePen

 var app = angular.module("myApp", []); app.controller("myCtrl", ['$scope', '$timeout', function($scope, $timeout) { $scope.myFoo = false; $scope.myBar = false; $scope.$watch("myFoo", function(n,o){ //$timeout(null,1500); console.log("watch > myFoo from: "+o+" to "+n+"; >"+$scope.myFoo); }); $scope.$watch("myBar", function(n,o){ //$timeout(null,500); console.log("watch > myBar from: "+o+" to "+n+"; >"+$scope.myBar); }); console.log("> Main thread: myFoo is: " + $scope.myFoo); console.log("> Main thread: myBar is: " + $scope.myBar); }]); 
 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script> <body> <div ng-app="myApp" ng-controller="myCtrl"> <div ng-init="myFoo=true;myBar=true"></div> </div> 

as we can see from the execution of that code

> Main thread: myFoo is: false
> Main thread: myBar is: false
watch > myFoo from: true to true; >true
watch > myBar from: true to true; >true

The main thread reaches the variables BEFORE its initialization... Bad !

You can fire a function on ng-init.

 var app = angular.module("myApp", []); app.controller("myCtrl", ['$scope', '$timeout', function($scope, $timeout) { $scope.myFoo = false; $scope.myBar = false; $scope.$watch("myFoo", function(n,o){ //$timeout(null,1500); console.log("watch > myFoo from: "+o+" to "+n+"; >"+$scope.myFoo); }); $scope.$watch("myBar", function(n,o){ //$timeout(null,500); console.log("watch > myBar from: "+o+" to "+n+"; >"+$scope.myBar); }); $scope.load = function(){ console.log("> Main thread: myFoo is: " + $scope.myFoo); console.log("> Main thread: myBar is: " + $scope.myBar); } }]); 
 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script> <body> <div ng-app="myApp" ng-controller="myCtrl"> <div ng-init="myFoo=true;myBar=true;load()"></div> </div> 

You could just wait for both variables to come back and then just destroy the listeners:

var app = angular.module("myApp", []);
app.controller("myCtrl", ['$scope', '$timeout', function($scope, $timeout) {


  $scope.myFoo = false;
  $scope.myBar = false;

  var fooListen = $scope.$watch("myFoo", function(n,o){
    console.log("watch > myFoo from: "+o+" to "+n);
    checkInit();
  });
  var barListen = $scope.$watch("myBar", function(n,o){
    console.log("watch > myBar from: "+o+" to "+n);
    checkInit();
  });

  function checkInit(){
    if($scope.myFoo && $scope.myBar){
      console.log("> Main thread: myFoo is: " + $scope.myFoo);
      console.log("> Main thread: myBar is: " + $scope.myBar);
      //remove the watches
      fooListen();
      barListen();
    }

  }

In this case each time a variable changes you would listen to the change. When both variables are initialized then you can run what ever code you want. But what about the $watches? you can actually tell them to stop listening. For more info on that you can look here: AngularJS : Clear $watch

And here is a updated pen: https://codepen.io/anon/pen/NvGOQE?editors=1112#anon-login

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM