在Angular中,我为包装ui-select
的可重用组件创建了一个指令(以自动化与REST服务的集成)。我的指令大致会被调用:
<rest-backed-selector selected-model="vm.selection"
service="abp.services.app.someservice"
on-select="vm.onSelect()">
根据可重用组件的最佳实践,该指令将隔离其范围(为了清楚起见,我省略了诸如templateUrl之类的辅助内容):
app.directive(
'restBackedSelector',
[ function () {
return {
scope: {
selectedModel: '=',
service: '@',
onSelect: '&'
}
};
]);
现在问题在于:$scope.selectedModel
需要通过模板传递给ui-select
:
<ui-select ng-model="selectedModel" ...>
这不起作用,因为从$scope
的顶级传递模型会在ui-select
控制器更改其值时破坏绑定,因为Angular的well-known gotcha范围继承。
推荐的解决方法是什么?
以下是问题的演示:http://plnkr.co/edit/XjGuXSjWFEfG4eyZL6sR?p=preview
通过在下拉列表中选择项目所做的更改不会反映在指令范围和顶级应用程序控制器中。一个部分解决方法是取消注释paged-select-box.js第26行,它将通过处理on-select事件显式更新外部作用域。但是,即使这样,源自外部范围的更改(例如点击重置按钮)也不会反映在ui选择范围内。
答案 0 :(得分:2)
当您拥有继承属性(或传递属性)的指令层次结构时,您的第一反应应该是不使用scope
属性而是使用bindToController
属性。
好处是:
controllerAs: 'vm',
scope: {},
bindToController: {
selection: '=',
requestFormat: '&',
itemFormat: '&'
}
使用controllerAs
模板需要遵循:
inner selection: {{ vm.selection.full_name }}
<ui-select ng-model="vm.selection"
on-select="vm.onSelect($item)">
<ui-select-match placeholder="Enter search term">{{ vm.itemFormat({ item: $select.selected }) }}</ui-select-match>
<ui-select-choices repeat="item in vm.items"
refresh="vm.requestFirstPage($select.search)">
<span ng-bind-html="vm.itemFormat({ item: item })"></span>
</ui-select-choices>
</ui-select>