我在一个页面上有几个多选项,每个都有一些逻辑来填充来自服务器的多选项。我想将每个选项包装成一个指令。
在尝试将这些内容包装到Directives之前,我按照这样构建了每个:
的index.html
<select name="groups" ng-model="inputs.groups" ng-change="groupsChanged()" ng-options="g for g in allgroups" multiple></select>
controllers.js
在第一遍中,我从这里开始我的$ http电话。是的,我知道,不是最佳做法,但我想先证明这对我自己有用。
$scope.loadSelect = function(_url) {
$http({
url: _url,
method: 'POST',
data: $scope.inputs,
model: 'all' + _url
}).success(function(data, status, headers, config) {
$scope[config.model] = data;
});
};
// Fill groups
$scope.loadSelect('groups');
// When groups change, reload other select fields that depend on groups
$scope.groupsChanged = function() {
$scope.loadSelect('categories');
$scope.loadSelect('actions');
}
现在我想将其迁移到指令。我看到两个主要挑战:
1.)如何将整套选项(例如现在的&#34; allgroups&#34;模型)封装到指令中?
2.)基于最初的实验,我尝试在模板中物理构建<select/>
,但意识到我必须操纵DOM来物理地替换name,ng-model和ng-options。这导致我转向编译属性,但是a。感觉不对,而且b。)设置<select ng-options="x for x in allgroups" />
在插入DOM之后实际上并没有重复。使用编译感觉不对;什么是正确的方法来解决这个问题?
这是我对该指令的第一次尝试看起来像这样。它没有真正起作用,我认为我不正确地做错了:
的index.html
<dimension ng-model="inputs.users" alloptions-model="allusers">Users</dimension>
directives.js
directive('dimension', function() {
return {
restrict: 'E',
scope: {
ngModel: '=',
alloptionsModel: '='
},
template:
'<div>' +
'<label ng-transclude></label>' +
'<fieldset>' +
'<div class="form-group">' +
'<select ng-model="{{ngModel}}" ng-options="x for x in {{alloptionsModel}}" multiple class="form-control"></select>' +
'</div>' +
'</fieldset>' +
'</div>',
replace: true,
transclude: true
};
});
显然我还没有进入服务器加载部分,但我计划将其转换为指令中的控制器,并在服务中使用实际的$ http调用。
我觉得我走错了轨道。如果您有关于如何重新调整的建议,请提供帮助!
答案 0 :(得分:1)
您的指令的主要问题是您不能在ngModel
和ngOptions
指令中使用胡子绑定,因为它们是直接计算的。您可以直接绑定到作用域属性(ngModel和alloptionsModel):
directive('dimension', function() {
return {
restrict: 'E',
scope: {
ngModel: '=',
alloptionsModel: '='
},
template:
'<div>' +
'<label ng-transclude></label>' +
'<fieldset>' +
'<div class="form-group">' +
'<select ng-model="ngModel" ng-options="x for x in alloptionsModel" multiple class="form-control"></select>' +
'</div>' +
'</fieldset>' +
'</div>',
replace: true,
transclude: true
};
});
有关工作示例,请参阅this plunkr。
修改强>
至于编译路线,它没有任何问题。当您需要动态创建模板时,这非常有用,当您到达select
的项目模板时,这将非常明显。
compile: function(tElement, tAttrs) {
var select = tElement.find('select'),
value = tAttrs.value ? 'x.' + tAttrs.value : 'x',
label = tAttrs.label ? 'x.' + tAttrs.label : 'x',
ngOptions = value + ' as ' + label + ' for x in alloptionsModel';
select.attr('ng-options', ngOptions);
}
// In the HTML file
<dimension ng-model="inputs.users"
alloptions-model="allusers"
label="name">
Users
</dimension>
我已使用编译功能更新了plunkr。