0

在上面的示例中,當我更改從控制器傳遞給指令的值數組時,所有更改都反映在指令html中。我的意思是我可以看到UI中的變化。在使用傳遞數據計算的本地作用域變量的自定義指令中,角度綁定不起作用

$scope.message變量的值的變化沒有得到體現,即使正在從$scope.myData值,在父控制器使用$timeout是得到改變其值計算的$scope.message值 要看到這些變化$scope.message,您需要使用$watchCollection來觀看陣列。我的問題是,

  1. 爲什麼angular的綁定在$scope.myData正常情況下不起作用?
  2. 角度綁定不起作用的其他「已知」角落案件是什麼?

下面的代碼片段

(function(){ 
    angular.module("csjoshi04.2waybinding",[]) 
      .controller("ParentCtrl",["$scope", "$timeout", function($scope, $timeout){ 
       $scope.myCars = ["Ford", "BMW", "Toyata"]; 
       $timeout(function(){ 
        $scope.myCars.push("Honda"); 
       }, 3000); 
      }]) 
      .directive("showMyData",function(){ 
       return { 
        restrict: "E", 
        scope: { 
         myData : "=" 
        }, 
        controller : ["$scope", function($scope){ 
         $scope.message = ($scope.myData.indexOf("Honda") > -1 && $scope.myData.length >= 4) ? "1 out of 4 cars is always Honda": "OOPS, no honda cars"; 
        }], 
        template : '<div>{{message}}</div><ul ng-repeat="data in myData"><li>{{data}}</li></ul>' 
       } 
      }) 
})() 

下面是HTML

<body ng-controller="ParentCtrl"><show-my-data my-data="myCars" ></show-my-data></body> 

爲了使上述指令的工作,我做了如下改變

directive("showMyData",function(){ 
       return { 
        restrict: "E", 
        scope: { 
         myData : "=" 
        }, 
        controller : ["$scope", function($scope){ 
         $scope.message = ($scope.myData.indexOf("Honda") > -1 && $scope.myData.length >= 4) ? "1 out of 4 cars is always Honda": "OOPS, no honda cars"; 
         $scope.$watchCollection(function(){ 
          return $scope.myData; 
         }, function(new1, old){ 
          $scope.message = ($scope.myData.indexOf("Honda") > -1 && $scope.myData.length >= 4) ? "1 out of 4 cars is always Honda": "OOPS, no honda cars"; 
         }); 
        }], 
        template : '<div>{{message}}</div><ul ng-repeat="data in myData"><li>{{data}}</li></ul>' 
       } 
      }) 

這裏是鏈接到plunkr。

plunker

回答

0

我不會把這個「極端情況」中的數據綁定角的

Angular的數據綁定通過不斷檢查附加到$ scope的值來工作。這很酷,但它不是魔術,在一個命令式語言如JavaScript語句 $scope.message = condition ? "message": "another message";本身不會表明這個表達式會再次被重新評估。 Angular僅對每個模板附件初始化控制器一次,而這正是上述示例中語句的評估次數。 一次。之後,它只是另一個$scope變量,它的值是「消息」或「另一個消息」,如果我們不改變它自己,那麼它將如何保持。

你已經發現了你自己的問題。 $scope.message的值取決於$scope.myData,但沒有$watchCollection,沒有什麼可以保持此連接的最新狀態。另一方面,$watchCollection將繼續重新評估$scope.myData;,然後是$scope.message = ...函數,因爲這是角度所要做的。

儘管如此,我會用函數getter來做,而不是將值賦給$scope並手動保持它是最新的。這更接近你最初試圖做的事情。

.directive("showMyData",function(){ 
    return { 
     restrict: "E", 
     scope: { 
      myData : "=" 
     }, 
     controller : ["$scope", function($scope){ 
      $scope.getMessage = function(){ 
       return ($scope.myData.indexOf("Honda") > -1 && $scope.myData.length >= 4) ? "1 out of 4 cars is always Honda": "OOPS, no honda cars"; 
      };  
     }], 
     template : '<div>{{getMessage()}}</div><ul ng-repeat="data in myData"><li>{{data}}</li></ul>' 
    } 
}) 

現在,我們使用的是函數調用,而不是一個簡單的值,創建該消息被重新評估一遍又一遍,在必要時更新視圖的表達。

+0

這是一個非常好的解決方案。它也有助於不使用$ scope。$ watch/Collection。一個問題,但在這個問題,爲什麼getter函數總是得到評估,而消息不是? – csjoshi04

+0

他們都得到評估。 使用'$ scope.message'控制器代碼將運行一次,'$ scope.message'將是「OOPS,沒有本田汽車」,因爲它運行時沒有本金。 Angular將繼續檢查'$ scope.message'的值是什麼,但不會改變。 Angular無法訪問或重新使用你的代碼'$ scope.message =($ scope.myData.indexOf(「Honda」)...'。 那indexOf檢查會運行一次然後它不見了,只是結果得到分配給'message',而不是整個語句 – noppa

+0

這就是語言在許多編程語言中的工作方式,但函數是不同的,它們內部的代碼可以並且會根據需要重新評估,與簡單的消息不同值,角度可以一遍又一遍地調用函數,並要求它重新評估值。 – noppa

相關問題