在包含另一个指令的可重用组件Angular指令中,如何创建模型"通过"?

时间:2016-09-25 13:39:06

标签: angularjs angularjs-directive angularjs-scope

在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选择范围内。

1 个答案:

答案 0 :(得分:2)

当您拥有继承属性(或传递属性)的指令层次结构时,您的第一反应应该是不使用scope属性而是使用bindToController属性。

好处是:

  • 您不必担心孤立的范围。
  • 您遵循最佳现代实践
  • 属性自动绑定到指令的控制器 你得到一个干净的对象点符号。
  • 你对范围的痛苦神奇地消失了

From the plunker

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>