AngularJS - 是否可以在链接或编译中的指令上更改ngModel属性的值

AngularJS - Is it possible to change the value of ngModel attribute on directive in link or compile?

本文关键字:指令 属性 ngModel 编译 是否 链接 AngularJS      更新时间:2023-09-26

我正在尝试创建一个指令,该指令将根据属性值将ngModel属性添加到标签中。 例如:

angular.module('myModule').
  directive('myDirective', function() {
    return {
      link: function(scope, elem, attrs) {
        var modelName = 'myPrefix.' + attrs.name;
        attrs.$set('ngModel', modelName);
      }
    };
  });

因此,此 html:

<input name="foo" my-directive></input>

被编译成

<input name="foo" ng-model="myPrefix.foo" my-directive></input>

它采用输入的名称,附加前缀,并将 ngModel 属性设置为该值。

当我尝试在链接函数中执行此操作时,似乎input没有向 formController 注册,因此form.foo返回未定义。

是否有可能完成我想要做的事情?

编辑:

似乎在 HTML 上设置了 ngModel 属性,但它未注册到表单中,或者 ngModelController 未实例化。 如果我查看作用域中ngModel的值,当我修改输入时,它不会改变。

您应该查看NgModelController的文档。 它将回答您的问题。 有关进一步的说明,要点如下:

您可以捕获link:函数的第四个参数,即您的ng-model值。 使用该对象来读取和设置模型。

link: function(scope, element, attrs, ngModel) {
    if(!ngModel) return; // do nothing if no ng-model
    // Specify how UI should be updated
    ngModel.$render = function() {
      element.html(ngModel.$viewValue || '');
    };
    // Listen for change events to enable binding
    element.on('blur keyup change', function() {
      scope.$apply(read);
    });
    read(); // initialize
    // Write data to the model
    function read() {
      var html = element.html();
      // When we clear the content editable the browser leaves a <br> behind
      // If strip-br attribute is provided then we strip this out
      if( attrs.stripBr && html == '<br>' ) {
        html = '';
      }
      ngModel.$setViewValue(html);
    }
}

希望有帮助。

我能够通过使用模板函数来实现目标。 我认为它在链接函数中不起作用,因为它发生在收集所有指令之后,因此编译器无法识别已添加ngModel指令。 不过,我不确定为什么它在编译函数中不起作用(即使我将优先级设置为 100)。

以下是该指令的工作版本:

angular.module('myModule').
  directive('myDirective', function() {
    return {
      replace: true,
      template: function(elem, attr) {
        var newElem = '<input ng-model="model.' + attr.name + '">';
        return newElem;
      }
    };
  });