2012-12-03 120 views
7

我很難搞清楚如何確保在創建指令時保持雙向數據綁定。以下是我與工作和小提琴:AngularJs指令中的數據綁定

http://jsfiddle.net/dkrotts/ksb3j/6/

HTML:

<textarea my-maxlength="20" ng-model="bar"></textarea> 
<h1>{{bar}}</h1> 

指令:

myApp.directive('myMaxlength', ['$compile', function($compile) { 
return { 
    restrict: 'A', 
    scope: {}, 
    link: function (scope, element, attrs, controller) { 
     element = $(element); 

     var counterElement = $compile(angular.element('<span>Characters remaining: {{charsRemaining}}</span>'))(scope); 

     element.after(counterElement); 

     scope.charsRemaining = parseInt(attrs.myMaxlength); 

     scope.onEdit = function() { 
      var maxLength = parseInt(attrs.myMaxlength), 
       currentLength = parseInt(element.val().length); 

      if (currentLength >= maxLength) { 
       element.val(element.val().substr(0, maxLength)); 
       scope.charsRemaining = 0; 
      } else { 
       scope.charsRemaining = maxLength - currentLength; 
      } 

      scope.$apply(scope.charsRemaining); 
     } 

     element.keyup(scope.onEdit) 
      .keydown(scope.onEdit) 
      .focus(scope.onEdit) 
      .live('input paste', scope.onEdit); 
     element.on('ngChange', scope.onEdit); 
    } 
} 
}]); 

正如我在textarea的種,型號沒有更新就像我需要它。我究竟做錯了什麼?

回答

0

我不完全確定,但我認爲你想要的是一個過濾器,看看這個網址,也許這是一個很好的方法來重新思考你的問題。

http://docs.angularjs.org/api/ng.filter:limitTo

+0

我不認爲這是我在這裏遇到的困難。我的問題非常簡單。在textarea上,我分配了一個模型。啓用myMaxlength指令後,該模型上的雙向綁定正在打破。 – Dustin

5

你真的需要一個自定義的指令? AngularJS附帶ngMaxlength指令,與ngChange結合可能會對您有所幫助。

例如,如果您有以下HTML

<body ng-controller="foo"> 
    <form name="myForm"> 
     <textarea name = "mytextarea" 
        ng-maxlength="20" 
        ng-change="change()" 
        ng-model="bar"></textarea> 
     <span class="error" ng-show="myForm.mytextarea.$error.maxlength"> 
      Too long! 
     </span> 
     <span> {{left}} </span> 
     <h1>{{bar}}</h1> 
    </form>     
</body> 

然後你只需要到這個控制器

function foo($scope) { 
    $scope.change = function(){ 
     if($scope.bar){ 
      $scope.left = 20 - $scope.bar.length;    
     }else{ 
      $scope.left = ""; 
     }  
    }; 
    $scope.bar = 'Hello'; 
    $scope.change(); 
} 

讓角處理DOM不亞於您可以。

下面是更新後的jsfiddle:http://jsfiddle.net/jaimem/ksb3j/7/

+0

我想使用內置的角度功能。但爲什麼不阻止在textarea中鍵入附加字符?這是我從maxlength期待的行爲。 –

12

好,有兩個原因導致的數據綁定雙向不起作用。 首先,你需要創建一個本地範圍屬性和父作用域屬性之間的雙向綁定:

scope: { bar: "=ngModel" } 

否則你創建一個孤立的範圍(見http://docs.angularjs.org/guide/directive)。

另一個原因是,你必須從父追加插入指示後更換(因爲你只是在dom.ready自舉角):

element.parent().append(counterElement); 

更新的jsfiddle:http://jsfiddle.net/andregoncalves/ksb3j/9/

+0

如果我提前不知道模型的名稱,我該怎麼做?另外,爲什麼你需要使用element.parent()。append()而不是element.after()? – Dustin

+1

如果您事先不知道模型名稱,最好不要使用聲明性的ng-model語法,並從控制器作用域中獲取模型(在指令中將範圍設置爲false)。關於element.parent()。append(),這是因爲你只是在dom.ready上引導角度,當指令運行時引導程序還沒有發生,從dom.ready處理程序中移除它,你可以在after ()。 –

+0

好的,我有一個更新的小提琴在這裏:http://jsfiddle.net/dkrotts/WWCzQ/3/。我現在遇到的問題是我的範圍變量charsRemaining需要與指令隔離,以便我可以在同一頁面上多次使用此指令。因爲它現在(範圍:false),charsRemaining在父範圍內共享,我需要該特定變量僅與指令隔離。 – Dustin

相關問題