2

これは、私が達成しようとしていることのjsfiddleの例です。

ビューが (333) 555-1212 として表示される米国の電話番号入力を作成しようとしていますが、モデルは整数 3335551212 にバインドされます。

私の意図は、カスタムバリデーターを追加するNgModelControllerことrequire: ng-modelです。分離スコープと を使用しない簡単なソリューションがありますがNgModelController、両方が必要です。

コンソールにすぐにエラーが表示されます: Error: Multiple directives [ngModel, ngModel] asking for 'ngModel' controller on: <input ng-model="user.mobile numeric" name="telephone" type="tel">-- I was using a isolate scope here...

4

2 に答える 2

5

@ mimir137をご覧いただきありがとうございますが、解決したようです:

http://jsfiddle.net/hr121r18/8/

ディレクティブは を使用していましたが、最終的には次のreplace: true構造になります。

<form ng-controller="FooCtrl" class="ng-scope">
    <p>Enter US phone number</p>
    <input ng-model="user.mobile numeric" name="telephone" type="tel">
</form>

必要なテンプレートとマークアップの両方がng-model原因で、問題の説明に症状のあるエラーが発生しました。それを削除すると、このマークアップにつながります(ラッパー要素に注意してくださいphone-number):

<form ng-controller="FooCtrl" class="ng-valid ng-scope ng-dirty ng-valid-parse" abineguid="BC0D9644F7434BBF80094FF6ABDF4418">
    <p>Enter US phone number</p>
    <phone-number ng-model="user.mobile" class="ng-untouched ng-valid ng-isolate-scope ng-dirty ng-valid-parse">
       <input ng-model="numeric" name="telephone" type="tel" class="ng-valid ng-dirty ng-touched">
    </phone-number>
</form>

ただし、これを削除すると、に変更が必要です$render。リンク関数にelem渡されるのは今phone-numberなので、掘り下げてそのinput内部を取得し、その値を設定する必要があります。

ngModel.$render = function () {
  elem.find('input').val($filter('phonenumber')(ngModel.$viewValue));
}; 

他にもいくつか問題がありました。 $render()ウォッチャーからも呼び出す必要がありました。

最後の:

var app = angular.module('myApp', []);

// i want to bind user.mobile to the numeric version of the number, e.g. 3335551212, but 
// display it in a formatted version of a us phone number (333) 555-1212
// i am trying to make the directive's scope.numeric to have two-way binding with the controller's
// $scope.user.mobile (using isolate scope, etc.).
app.controller('FooCtrl', function ($scope) {
    $scope.user = {
        mobile: 3335551212
    };
});

app.directive('phoneNumber', ['$filter', function ($filter) {
    return {
        restrict: 'E',
        template: '<input ng-model="numeric" name="telephone" type="tel">',
        require: 'ngModel',
        scope: {
            numeric: '=ngModel'
        },
        link: function (scope, elem, attrs, ngModel) {

            // update $viewValue on model change
            scope.$watch('numeric', function () {
                ngModel.$setViewValue(scope.numeric);
                ngModel.$render();
            });

            // $modelValue convert to $viewValue as (999) 999-9999
            ngModel.$formatters.push(function (modelValue) {
                return $filter('phonenumber')(String(modelValue).replace(/[^0-9]+/, ''));
            });

            // $viewValue back to model
            ngModel.$parsers.push(function (viewValue) {
                var n = viewValue;
                if (angular.isString(n)) {
                    n = parseInt(n.replace(/[^0-9]+/g, ''));
                }
                return n;
            });

            // render $viewValue through filter
            ngModel.$render = function () {
                elem.find('input').val($filter('phonenumber')(ngModel.$viewValue));
            };

        }
    };
}]);

app.filter('phonenumber', function () {
    return function (number) {
        if (!number) {
            return '';
        }
        number = String(number);
        var formattedNumber = number;
        var c = (number[0] === '1') ? '1 ' : '';
        number = number[0] === '1' ? number.slice(1) : number;

        var area = number.substring(0, 3),
            exchange = number.substring(3, 6),
            subscriber = number.substring(6, 10);

        if (exchange) {
            formattedNumber = (c + '(' + area + ') ' + exchange);
        }
        if (subscriber) {
            formattedNumber += ('-' + subscriber);
        }
        return formattedNumber;
    }
});

HTML

<form ng-controller="FooCtrl">
    <p>Enter US phone number</p>
    <phone-number ng-model='user.mobile'></phone-number>
</form>
于 2015-02-15T04:52:21.687 に答える
0

コンソールに表示されるほとんどのエラーを取り除くこのフィドルを作成しました。うまくいけば、これは少なくともあなたを正しい軌道に乗せることができるでしょう.

フィルターが実際に機能していることを確認できるように、テンプレートを変更しました。これで{{ngModel | FilterName}}、テキスト ボックスの下に典型的なプレーン テキストが表示されます。唯一の本当の問題は、テキストボックスに表示することです。私はあなたがそれで問題ないと確信しています。これに関してまだ質問がある場合に備えて、午前中に確認します。

編集:あなたはすでにそれを解決しているようです。よくやった!

于 2015-02-15T03:39:13.483 に答える