2013-08-19 28 views
1

我想寫一個指令,允許我們從列表中刪除值。 HTML和Javascript代碼如下所示即使將函數作爲事件處理程序的一部分調用,爲什麼還需要scope.apply?

HTML

<body ng-app="evalModule"> 
    <div ng-controller="Ctrl1"> 
     <input type="text" ng-model="newFriend"></input> 
     <button ng-click="addFriend()">Add Friend</button> 
     <ul> 
      <li ng-repeat="friend in friends"> 
       <div class='deletable' index-value = {{$index}} delete-function="removeFriend(frndToRemove)"> {{$index}} {{friend}} </div> 
      </li> 
     </ul> 
    </div> 
</body> 

的Javascript

function Ctrl1 ($scope) { 
    $scope.friends = ["Jack","Jill","Tom"]; 

    $scope.addFriend = function() { 
     $scope.friends.push($scope.newFriend); 
    } 

    $scope.removeFriend = function (indexvalue) { 
     console.log(indexvalue); 
     var index = $scope.friends.indexOf(indexvalue); 
     $scope.friends.splice(indexvalue, 1); 
    } 
} 

var evalModule = angular.module("evalModule",[]); 

evalModule.directive('deletable', function(){ 
    return{ 
     restrict : 'C', 
     replace : true, 
     transclude : true, 
     scope:{ 
      indexValue : '@indexValue', 
      deleteFunction : '&' 
     }, 
     template : '<div>'+ 
         '<div> X </div>'+ 
         '<div ng-transclude></div>'+ 
        '</div>', 
     link:function(scope, element, attrs){ 
      var del = angular.element(element.children()[0]); 
      del.bind('click',deleteValue); 

      function deleteValue() { 
       var expressionHandler = scope.deleteFunction; 
       expressionHandler({frndToRemove : scope.indexValue}); 
       console.log("deleteValue called with index" + attrs.indexValue); 
       scope.$apply(); 
      } 
     } 
    } 
}); 

Link to JSFiddle

爲什麼我需要調用範圍。$即使代碼綁定爲應用按鈕點擊事件的事件。根據這裏的文檔http://docs.angularjs.org/guide/scope這應該是「Angular領域」的一部分。

有人能幫助我理解角域,同時澄清上述?任何關於改進上述代碼的反饋也將讚賞。

+0

按鈕點擊不是'ng-click'。閱讀有關角度的編譯>鏈接階段。這應該給你一個很好的概述。 –

回答

4

正如@DavinTyron所說,按鈕點擊事件是一個外部事件,不屬於「Angular領域」的一部分。所以你需要調用$scope.$apply()以觸發摘要循環並更新DOM。

儘管如此,您並不需要手動綁定click事件。您可以使用ng-click代替:

template: '<div>'+ 
      '<div ng-click="delete()"> X </div>'+ 
      '<div ng-transclude></div>'+ 
      '</div>', 
link: function(scope) { 
    scope.delete = function() { 
     scope.deleteFunction({frndToRemove : scope.indexValue}); 
     console.log("deleteValue called with index" + attrs.indexValue);     
    }; 
} 

由於ng-click正在被使用,就沒有必要打電話$scope.$apply()。這是你的jsFiddle的modified version

相關問題