我有一个输入元素,我想使用自定义指令将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/
答案 0 :(得分: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/
答案 1 :(得分: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);
}
};
});
答案 2 :(得分: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(元素),但它会生成大量信息。最好在页面加载后检查元素,以查看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之间的语法差异。