10

我有一个输入元素,我想使用自定义指令将 ngModel 和 ngClass 绑定到它,但我遇到了一些麻烦。

我有的:

<input type="text" myDirective="PropertyFromScope" />

我想要的结果:

<input type="text" ng-model="PropertyFromScope" ng-class="{'class' : MethodFromScope}" />

我试图避免使用模板,因为我希望该指令可以与任何输入标签一起使用。

这是我到目前为止得到的:

angular.module('customDirectives', [])
.directive('myDirective', function () {
    var linker = function (scope, element, attrs) {
        attrs.$set('ngModel', attrs.myDirective);
        attrs.$set('ngClass', '{\'class\' : MethodFromScope}');
    }
    return {
        restrict: 'A',        
        link: linker
    }
});

这是一个 JSFiddle:http: //jsfiddle.net/Q8QJJ/

4

3 回答 3

12

你想做到这一点吗?

非常简单的解决方案:

myApp.directive('myDirective', function ($compile) {
    return {
        restrict: 'A',        
        compile: function(element, attrs) {
            element.attr('ng-model', attrs.myDirective);
            element.removeAttr("my-directive");
            element.attr('ng-class', '{\'class\' : testFunction()}');
            return {
               pre: function preLink(scope, iElement, iAttrs, controller) { },
               post: function postLink(scope, iElement, iAttrs, controller) { 
                 $compile(iElement)(scope);
               }
            }
        }
    }
});

这是一个小提琴http://jsfiddle.net/V9e9M/

于 2013-07-01T14:19:23.490 回答
2

我无法让它在编译函数中工作(它添加了属性,但似乎没有注意到它们)。但是,此链接功能似乎有效:

myApp.directive('myDirective', function ($compile) {
    return {
        restrict: 'A',
        link: function (scope, element, attrs) {
            var wrappedElement = angular.element(
                '<input type="' + attrs.type + '" ng-model="' 
                 + attrs.myDirective + '">');
            element.replaceWith(wrappedElement);
            $compile(wrappedElement)(scope);
        }
    }
});

小提琴

注意:我忘记添加 ng-class,但我假设如果 ng-model 有效,ng-class 应该有效。

更新

这是一个使用编译功能的版本:

myApp.directive('myDirective', function () {
    return {
        restrict: 'A',
        compile: function (tElement, tAttrs) {
            // for some unknown-to-me reason, the input must
            // be wrapped in a span or div:
            var tplElement = angular.element('<span><input></span>');
            var inputEl = tplElement.find('input');
            inputEl.attr('type', tAttrs.type);
            inputEl.attr('ng-model', tAttrs.myDirective);
            tElement.replaceWith(tplElement);
        }
    };
});

小提琴

于 2013-07-09T01:28:04.057 回答
1

我登陆这个页面时遇到了类似的问题,将 ngModel 与自定义指令绑定。这个问题已经有几年了,但也许我的解决方案会对其他人有所帮助。

首先,在 index.html 中,我使用了带有一些组成属性的自定义指令。请注意 html 中的破折号。属性值是我想在指令中使用的。

index.html

<div>
    <form name="userInfo">
        <my-custom-directive for-model="ctrl.userInput"
                             for-label="Enter User Info"
                             for-other="more info for the directive">
        <my-custom-directive>
    </form>
</div>
// check to see the binding.
{{ ctrl.userInput }}

接下来,在 partial.html 中,我将设置一些默认值,以查看指令何时正常工作,以及何时看到默认值。

partial.html

<div class="form-group">
    <label>blankLabel</label>
    <input type="text"
           class="form-control"
           ng-model="modelBlank">
</div>

该指令需要一些不同的语法,这可能是最常见的问题。我喜欢定义一个变量,因为我可能会分配多个属性。然后在变量上调用 .attr() 并传递您要应用的新信息。在这种情况下,字面意思是“ng-model”和 index.html 中设置的自定义属性的值。

directive.js

.directive('myCustomDirective', function () {
    return {
        templateUrl: 'partial.html',
        compile: function (element, attributes) {
            // Find the right element in the partial and assign a variable
            var inputTag = element.find('input');
            // use .attr() on the variable and pass it two arguments.
            inputTag.attr('ng-model', attributes.forModel);
            // Find a different element in the partial and replace the text.
            var labelTag = element.find('label');
            labelTag.html(attributes.forLabel);
        }
    };
})

您可以使用 console.log(element),但它会生成大量信息。最好在页面加载后检查元素以查看 ng-model 设置为自定义值。如果连接正确,index.html 页面上的 {{ ctrl.userInput }} 应该会显示输入到表单中的文本。

这是很多工作,但现在 myCustomDirective 可以通过传入的不同信息重用:

<my-custom-directive for-model="ctrl.userName"
                     for-label="Enter Your Name:"
                     for-other="more info for the directive">
<my-custom-directive>
<my-custom-directive for-model="ctrl.userSelection"
                     for-label="Make a selection:"
                     for-other="more info for the directive">
<my-custom-directive>

就个人而言,我从来没有遇到过使用这种方法添加属性或角度指令的问题,包括像 uib-typeahead 这样的东西。请记住观察 html 和 javascript 之间的语法差异。

于 2016-02-14T18:16:19.047 回答