【问题标题】:custom input directive using ngModel does not update model value使用 ngModel 的自定义输入指令不会更新模型值
【发布时间】:2015-12-09 15:49:55
【问题描述】:

我想在自定义输入指令中使用 ngPattern。为了玩耍,我首先创建了以下指令:

myApp.directive('myInput', [function() {
    return{
        restrict: 'A',
        replace: true,
        require: 'ngModel',
        scope: true,
        template:
            '<div>' +
            '  <input type="text" ng-model="val" ng-change="updateValue()" ng-pattern="/^-?(?:\d+|\d*\.(\d+)?)$/i">' +
            '</div>',
        link: function(scope, element, attrs, ngModelCtrl){     
            scope.updateValue = function(){
                ngModelCtrl.$setViewValue(scope.val);
            }

            ngModelCtrl.$render = function () {
                scope.val = ngModelCtrl.$viewValue;
            };
        }
    };
}]);

我在调试器中看到scope.val 的值始终未定义,因此调用$setValue 无效。我试图删除 ng-pattern 属性,但更新也不起作用。

这里有什么问题? plunkr 可以在 here 找到,我绑定到模型而不是原始对象!

更新

似乎在scope.updateValue 中调用ngModelCtrl.$setViewValue(scope.val) 有一个奇怪的结果。如果有这样的模型:

scope.model = {
    'testValue' : 12
};

然后我绑定到"model.testValue"(如plunkr)然后模型在ngModelCtrl.$setViewValue(scope.val) 执行后变成一个空对象{}。在普通输入字段中再次设置该值会将scope.model 变量重置为一个健全的对象。对我来说这毫无意义。知道为什么会这样吗?

【问题讨论】:

    标签: javascript angularjs angularjs-directive


    【解决方案1】:

    我自己找到了解决方案。我不确定这是否是最好的方法,但它有效。我看到了与我的原始版本非常相似的指令(从某种意义上说,数据绑定是如何实现的),例如jkuri.touchSpin

    重要的是保留ngModelController的原始$render函数的引用,并在使用$setViewValue后调用该函数。

    但最终对我有用的是:

    myApp.directive('myInput', ['$parse', function($parse) {
        return{
            restrict: 'A',
            replace: true,
            require: 'ngModel',
            scope: true,
            template:
                '<div>' +
                '  <input type="text" ng-model="val" ng-change="updateValue()"  ng-pattern="regex" >' +
                '</div>',
            link: function(scope, element, attrs, ngModelCtrl){
                var orignalRender = ngModelCtrl.$render;
                scope.regex = /^-?(?:\d+|\d*\.(\d+)?)$/i;
                ngModelCtrl.$render = function () {
                    scope.val = ngModelCtrl.$viewValue;
                };              
                scope.updateValue = function(){
                    ngModelCtrl.$setViewValue(scope.val);
                    orignalRender();
                }
            }
        };
    }]);
    

    【讨论】:

      【解决方案2】:

      经验法则:

      你传递给 ng-model 的任何东西都应该有一个 .这意味着您不想绑定到原语。

      https://www.youtube.com/watch?v=ZhfUv0spHCY&feature=youtu.be&t=30m

      https://github.com/angular/angular.js/wiki/Understanding-Scopes#javascript-prototypal-inheritance

      【讨论】:

      • 正如您在 plunkr 中看到的那样,有一个“.”,所以我绑定的是模型而不是原语。
      • 我认为他在模板字符串中指的是您的 ng-model,而您没有使用“。”
      猜你喜欢
      • 2016-12-04
      • 1970-01-01
      • 2016-10-02
      • 1970-01-01
      • 1970-01-01
      • 2017-05-05
      • 2017-01-02
      • 1970-01-01
      • 2014-05-03
      相关资源
      最近更新 更多