Javascript AngularJS请求ngModel的多个指令

Javascript AngularJS请求ngModel的多个指令,javascript,angularjs,angularjs-directive,angularjs-ng-model,Javascript,Angularjs,Angularjs Directive,Angularjs Ng Model,以下是我试图实现的目标 我试图构建一个美国电话号码输入,其中视图显示为(333)555-1212,但模型绑定到数字整数3335551212 我的目的是将自定义验证器添加到NgModelController,这就是为什么我有require:ng model;有一些更简单的解决方案没有隔离范围和NgModelController,但我需要两者 您将在控制台中看到一个即时错误:error:multipledirectives[ngModel,ngModel]要求在上设置“ngModel”控制器:--我

以下是我试图实现的目标

我试图构建一个美国电话号码输入,其中视图显示为(333)555-1212,但模型绑定到数字整数3335551212

我的目的是将自定义验证器添加到
NgModelController
,这就是为什么我有
require:ng model
;有一些更简单的解决方案没有隔离范围和
NgModelController
,但我需要两者

您将在控制台中看到一个即时错误:
error:multipledirectives[ngModel,ngModel]要求在上设置“ngModel”控制器:
--我在这里使用了一个隔离作用域…

我创建了一个用于消除控制台中出现的大多数错误的指令。希望这至少能让你走上正轨

我更改了模板,以便您可以看到过滤器实际工作。 现在,它在文本框下面有典型的纯文本
{{ngModel | FilterName}
。 唯一真正的问题是在文本框中显示它。我相信你不会有问题的。我会在早上检查,以防你对此还有疑问


编辑:好吧,看来你已经解决了。干得好

感谢您寻找@mimir137,但我似乎已经解决了这个问题:

该指令使用的是
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>
但删除此项需要对
$render
进行更改;传递到link函数的
元素现在是
电话号码
,因此您需要挖掘以获取其中的
输入
,并设置该值:

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;
    }
});
var-app=angular.module('myApp',[]);
//我想将user.mobile绑定到数字版本,例如3335551212,但是
//以美国电话号码(333)555-1212的格式化版本显示
//我正在尝试使指令的scope.numeric与控制器的
//$scope.user.mobile(使用隔离作用域等)。
应用程序控制器('FooCtrl',函数($scope){
$scope.user={
手机:3335551212
};
});
app.directive('phoneNumber',['$filter',function($filter){
返回{
限制:'E',
模板:“”,
要求:'ngModel',
范围:{
数值:'=ngModel'
},
链接:功能(范围、要素、属性、ngModel){
//在模型更改时更新$viewValue
作用域:$watch('numeric',函数(){
ngModel.$setViewValue(scope.numeric);
ngModel.$render();
});
//$modelValue转换为$viewValue as(999)999-9999
ngModel.$formatters.push(函数(modelValue){
返回$filter('phonenumber')(字符串(modelValue)。替换(/[^0-9]+/,'');
});
//$viewValue返回模型
ngModel.$parsers.push(函数(viewValue){
var n=视图值;
if(角度isString(n)){
n=parseInt(n.replace(/[^0-9]+//g');
}
返回n;
});
//通过过滤器渲染$viewValue
ngModel.$render=函数(){
元素find('input').val($filter('phonenumber')(ngModel.$viewValue));
};
}
};
}]);
app.filter('phonenumber',函数(){
返回函数(编号){
如果(!编号){
返回“”;
}
数字=字符串(数字);
var formattedNumber=编号;
变量c=(数字[0]='1')?'1':'';
编号=编号[0]=“1”?编号。切片(1):编号;
var区域=子字符串(0,3)的数量,
交换=数字。子字符串(3,6),
订户=数字。子串(6,10);
如果(交换){
格式化的数字=(c+'('+区域+')'+交换);
}
if(订户){
formattedNumber+=('-'+订户);
}
返回格式化的数字;
}
});
HTML


输入美国电话号码


我有一个自定义过滤器-不确定您是否查看了小提琴。您在代码中所做的更改并不明显,但很高兴您找到了解决方案。@Claies比较begin fiddle:(这是一个完全的黑客竞赛)和end fiddle:如果我真的对差异感兴趣,我可以比较它们,但一个好的答案并不依赖于未来可能不存在的小提琴或其他东西的链接。任何有类似问题并发现您的问题的人都是在寻找一些东西来解释问题所在,而不是他们需要比较和对比的代码。
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;
    }
});
<form ng-controller="FooCtrl">
    <p>Enter US phone number</p>
    <phone-number ng-model='user.mobile'></phone-number>
</form>