9

我正在尝试创建一个指令,该指令将根据属性值将 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返回未定义。

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

编辑:

似乎该ngModel属性是在 HTML 上设置的,但它没有在表单中注册,或者 ngModelController 没有被实例化。如果我查看ngModel范围内的值,当我修改输入时它不会改变。

4

2 回答 2

5

您应该查看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);
    }
}

希望有帮助。

于 2013-10-25T00:00:02.960 回答
3

I was able to accomplish the goal by using a template function. I think it doesn't work in the link function because it occurs after all of the directives have been collected, so the compiler doesn't recognize that an ngModel directive has been added. I'm not sure why it doesn't work in the compile function, though (even if I set the priority to 100).

Here's the working version of the directive:

angular.module('myModule').
  directive('myDirective', function() {
    return {
      replace: true,
      template: function(elem, attr) {
        var newElem = '<input ng-model="model.' + attr.name + '">';
        return newElem;
      }
    };
  });
于 2013-10-25T18:44:24.087 回答