2012-12-03 25 views
7

Mam trudności z ustaleniem, jak zachować dwukierunkowe powiązanie danych podczas tworzenia dyrektyw. Oto co ja pracuję z i skrzypce:Powiązanie danych w dyrektywie AngularJs

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

HTML:

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

dyrektywa:

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); 
    } 
} 
}]); 

Jak wpisać textarea, model nie jest aktualizowanie tak jak tego potrzebuję. Co ja robię źle?

Odpowiedz

0

Nie jestem do końca pewien, ale myślę, że to, co chcesz filtrować, spójrz na ten adres URL, może jest to świetne podejście do ponownego przemyślenia twojego problemu.

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

+0

Nie sądzę, że to jest to, z czym mam tutaj trudności. Mój problem jest dość prosty. W obszarze tekstowym mam przypisany model. Dwustronne wiązanie tego modelu jest przerwane po włączeniu dyrektywy myMaxlength. – Dustin

5

Czy naprawdę trzeba dyrektywę niestandardowy? AngularJS z dyrektywą ngMaxlength w połączeniu z ngChange może ci pomóc.

Na przykład, jeśli masz następujący kod 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> 

Potem wystarczy to do swojego kontrolera

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

Niech kątowe obsłużyć DOM tak bardzo jak to tylko możliwe.

Oto zaktualizowana jsfiddle: http://jsfiddle.net/jaimem/ksb3j/7/

+0

Chciałbym użyć wbudowanej funkcji kątowej. Ale dlaczego to nie powstrzymuje dodatkowych znaków przed wpisaniem w tekście? Takie zachowanie oczekiwałem od maksymalnej długości. –

12

Cóż, istnieją dwa powody, dla których dwukierunkowe wiązania z danymi nie działa. Najpierw trzeba utworzyć dwukierunkowe wiązanie pomiędzy lokalnym mienia zakres i mienia zakres parent:

scope: { bar: "=ngModel" } 

inaczej jesteś tworząc wyizolowaną zakresu (patrz http://docs.angularjs.org/guide/directive).

Drugim powodem jest to, że trzeba wymienić po instrukcji insert z append od rodzica (bo są tylko ładowanie początkowe kątowe na dom.ready):

element.parent().append(counterElement); 

Aktualizacja jsfiddle: http://jsfiddle.net/andregoncalves/ksb3j/9/

+0

Jak to zrobić, jeśli nie znałem nazwy modelu z wyprzedzeniem? Ponadto, dlaczego musisz użyć elementu element.parent(). Append() zamiast elementu element.after()? – Dustin

+1

Jeśli nie znasz nazwy modelu z wyprzedzeniem, lepiej nie używaj deklaratywnej składni modelu ng i pobierz model z zakresu kontrolera (ustaw zakres na wartość false w dyrektywie). Jeśli chodzi o element.parent(). Append(), to dlatego, że tylko ładuje się kątowo w dom.ready i kiedy dyrektywa uruchamia bootstrap jeszcze się nie pojawił, usuń go z obsługi dom.ready i możesz użyć po(). –

+0

Ok Mam zaktualizowane skrzypce tutaj: http://jsfiddle.net/dkrotts/WWCzQ/3/. Problem, który mam teraz, to mój zakres zmiennych chowańców. Odblokowanie musi być odizolowane od dyrektywy, aby móc korzystać z tej dyrektywy wielokrotnie na tej samej stronie. Tak jak jest teraz (z zasięgiem: false), charsRemaining jest współdzielony przez zakres nadrzędny i potrzebuję, aby ta konkretna zmienna była odizolowana tylko od dyrektywy. – Dustin

Powiązane problemy