AngularJS - 如何在custom指令中更改ngModel的值?

Sad*_*ady 42 javascript angularjs angularjs-directive angularjs-model

让我们来看看我的指令:

angular.module('main').directive('datepicker', [
function() {
    return {
        require: '?ngModel',
        link: function(scope, element, attributes, ngModel) {
            ngModel.$modelValue = 'abc'; // this does not work
            // how do I change the value of the model?
Run Code Online (Sandbox Code Playgroud)

那么,我该如何改变ng模型的值呢?

Car*_*ona 49

有不同的方法:

  1. $setViewValue()更新视图和模型.大多数情况就足够了.
  2. 如果要断开视图与模型的连接(例如,模型是一个数字,但视图是一个包含数千个分隔符的字符串),那么您可以直接访问$viewValue$modelValue
  3. 如果你还想覆盖内容ng-model(例如指令改变小数位数,也更新模型),注入ngModel: '='范围并设置scope.ngModel

例如

  return {
     restrict: 'A',
     require: 'ngModel',
     scope: {
         ngModel: '='
     },
     link: function (scope, element, attrs, ngModelCtrl) {

        function updateView(value) {
            ngModelCtrl.$viewValue = value;
            ngModelCtrl.$render(); 
        }

        function updateModel(value) {
            ngModelCtrl.$modelValue = value;
            scope.ngModel = value; // overwrites ngModel value
        }
 ...
Run Code Online (Sandbox Code Playgroud)

链接:

  • 唉唉!最后.谢谢"brah"!我错过了`scope ngModel:'='` (4认同)

Sly*_*nal 28

要使用复杂的绑定表达式,您应该使用$ parse服务和assign方法.

有关更多信息,请观看ng-conf中的视频 - 这是关于使用ng-model指令可以做的很酷的事情:https://www.youtube.com/watch?v = jVzymluqmg4

app.directive('datepicker', ['$parse',
    function($parse) {
        return {
            require: '?ngModel',
            link: function(scope, element, attributes, controller) {
                // $parse works out how to get the value.
                // This returns a function that returns the result of your ng-model expression.
                var modelGetter = $parse(attributes['ngModel']);
                console.log(modelGetter(scope));

                // This returns a function that lets us set the value of the ng-model binding expression:
                var modelSetter = modelGetter.assign;

                // This is how you can use it to set the value 'bar' on the given scope.
                modelSetter(scope, 'bar');

                console.log(modelGetter(scope));
            }
        };
    }
]);
Run Code Online (Sandbox Code Playgroud)


gle*_*tre 4

你所尝试的实际上是有效的:请参阅此 Plunker

您不会在输入中“看到”它,因为以这种方式更改模型不会调用controller.$render()设置新的 controller.$viewValue.

但为什么不简单地改变这个$scope值(除非你不知道,但这会很奇怪):

angular.module('main').directive('datepicker', [function() {
    return {
        require: '?ngModel',
        link: function(scope, element, attributes, controller) {
          var model = attributes['ngModel'];
          scope[model] = 'bar';
        }
    };
}]);
Run Code Online (Sandbox Code Playgroud)

在你的html中:

<input ng-model="yourVariable" datepicker>
Run Code Online (Sandbox Code Playgroud)

编辑:(动态解决方案)

angular.module('main').directive('datepicker', [function() {
    return {
        require: '?ngModel',
        link: function(scope, element, attributes, controller) {
          // get the value of the `ng-model` attribute
          var model = attributes['ngModel'];

          // update the scope if model is defined
          if (model) {
            scope[model] = 'bar';
          }
        }
    };
}]);
Run Code Online (Sandbox Code Playgroud)