7

ディレクティブを作成するときに双方向のデータ バインディングを確実に維持する方法を理解するのに苦労しています。これが私が取り組んでいるものとフィドルです:

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

テキストエリアに入力すると、必要なようにモデルが更新されません。私は何を間違っていますか?

4

3 に答える 3

12

双方向データバインディングが機能しない理由は 2 つあります。まず、ローカル スコープ プロパティと親スコープ プロパティの間に双方向バインディングを作成する必要があります。

scope: { bar: "=ngModel" }

それ以外の場合は、分離されたスコープを作成しています ( http://docs.angularjs.org/guide/directiveを参照)。

もう 1 つの理由は、挿入後の命令を親からの追加に置き換える必要があることです (dom.ready で angular のみをブートストラップしているため)。

element.parent().append(counterElement);

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

于 2012-12-03T19:26:18.183 に答える
5

カスタム ディレクティブは本当に必要ですか? ngMaxlengthAngularJS には、と組み合わせたディレクティブが付属してい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();
}

angular に dom をできる限り処理させます。

更新された jsfiddle は次のとおりです: http://jsfiddle.net/jaimem/ksb3j/7/

于 2012-12-03T18:58:02.387 に答える
0

完全にはわかりませんが、フィルターが必要だと思います。この URL を見てください。問題を再考するための優れたアプローチである可能性があります。

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

于 2012-12-03T17:57:39.217 に答える