我正在创建一个选择替换指令,以便根据设计轻松选择样式,而不必总是对一堆标记(即指令为你做的!)。
我没有意识到属性不会转移到放置ng-transclude
的位置,只是转到根元素。
我在这里有一个例子:http://plnkr.co/edit/OLLntqMzbGCJS7g7h1j4?p=preview
你可以看到它看起来很棒......但是有一个主要的缺陷。 id
和name
属性未被转移。你知道,如果没有name
,它就不会发布到服务器上(这种形式与现有系统相关联,因此AJAXing模型不是一种选择)。
例如,这就是我的开始:
<select class="my-select irrelevant-class" name="reason" id="reason" data-anything="banana">
<option value="">Reason for Contact...</option>
<option>Banana</option>
<option>Pizza</option>
<option>The good stuff</option>
<option>This is an example of a really, really, really, really, really, really long option item</option>
</select>
...这就是我想要它的样子:
<div class="faux-select" ng-class="{ placeholder: default == viewVal, focus: obj.focus }">
<span class="faux-value">{{viewVal}}</span>
<span class="icon-arrow-down"></span>
<select ng-model="val" ng-focus="obj.focus = true" ng-blur="obj.focus = false" ng-transclude class="my-select irrelevant-class" name="reason" id="reason" data-anything="banana">
<option value="">Reason for Contact...</option>
<option>Banana</option>
<option>Pizza</option>
<option>The good stuff</option>
<option>This is an example of a really, really, really, really, really, really long option item</option>
</select>
</div>
...但这就是实际发生的事情:
<div class="faux-select my-select irrelevant-class" ng-class="{ placeholder: default == viewVal, focus: obj.focus }" name="reason" id="reason" data-anything="banana">
<span class="faux-value">{{viewVal}}</span>
<span class="icon-arrow-down"></span>
<select ng-model="val" ng-focus="obj.focus = true" ng-blur="obj.focus = false" ng-transclude>
<option value="">Reason for Contact...</option>
<option>Banana</option>
<option>Pizza</option>
<option>The good stuff</option>
<option>This is an example of a really, really, really, really, really, really long option item</option>
</select>
</div>
具体来说,问题是select上没有name
属性,所以它实际上并没有将数据发送到服务器。
显然,我可以使用预编译阶段来传输name
和id
属性(这就是我现在正在做的事情),但如果它只是自动传输会很好em>所有属性,以便他们可以添加任何类,任意数据,(ng-)必需,(ng-)禁用属性等等。
我尝试让transclude: 'element'
正常工作,但之后我无法将模板中的其他属性添加到其中。
注意,我在这里看到了帖子:How can I transclude into an attribute?,但看起来他们只是手动传输数据,我的目标是让它自动传输所有属性。
答案 0 :(得分:5)
您可以使用compile函数访问元素的属性并构建模板。
app.directive('mySelect', [function () {
return {
transclude: true,
scope: true,
restrict: 'C',
compile: function (element, attrs) {
var template = '<div class="faux-select" ng-class="{ placeholder: default == viewVal, focus: obj.focus }">' +
'<span class="faux-value">{{viewVal}}</span>' +
'<span class="icon-arrow-down entypo-down-open-mini"></span>' +
'<select id="' + attrs.id + '" name="' + attrs.name + '" ng-model="val" ng-focus="obj.focus = true" ng-blur="obj.focus = false" ng-transclude>';
'</select>' +
'</div>';
element.replaceWith(template);
//return the postLink function
return function postLink(scope, elem, attrs) {
var $select = elem.find('select');
scope.default = scope.viewVal = elem.find('option')[0].innerHTML;
scope.$watch('val', function(val) {
if(val === '') scope.viewVal = scope.default;
else scope.viewVal = val;
});
if(!scope.val) scope.val = $select.find('option[selected]').val() || '';
}
}
};
}]);
编译函数返回postLink函数,还有其他方法可以执行此操作,您将找到更多信息here。
答案 1 :(得分:0)
ng-transclude
转换放置指令的元素的内容。我会将该属性分配给其父div并转换模板中的整个选择框:
第一种方法:
http://plnkr.co/edit/fEaJXh?p=preview
<div class="form-control my-select">
<select class="irrelevant-class" name="reason" id="reason" data-anything="banana">
<option value="">Reason for Contact...</option>
<option>Banana</option>
<option>Pizza</option>
<option>The good stuff</option>
<option>This is an example of a really, really, really, really, really, really long option item</option>
</select>
</div>
从定义中删除替换选项:
app.directive('mySelect', [function () {
return {
template:
'<div class="faux-select" ng-class="{ placeholder: default == viewVal, focus: obj.focus }">' +
'<span class="faux-value">{{viewVal}}</span>' +
'<span class="icon-arrow-down entypo-down-open-mini"></span>' +
'<div ng-transclude></div>' +
'</div>',
transclude: true,
//replace: true,
scope: true,
restrict: 'C',
link: function (scope, elem, attrs) {
var $select = elem.find('select');
scope.default = scope.viewVal = elem.find('option')[0].innerHTML;
scope.$watch('val', function(val) {
if(val === '') scope.viewVal = scope.default;
else scope.viewVal = val;
});
if(!scope.val) scope.val = $select.find('option[selected]').val() || '';
}
};
}]);
第二种方法: 在您的演示中,只需在链接方法的末尾包含以下行:
$select.attr({'id': elem.attr('id'), 'name': elem.attr('name')});