Tabs指令不在我的范围中公开api

时间:2014-07-16 08:21:36

标签: angularjs angularjs-directive angularjs-scope angular-ui-bootstrap

所以我尝试使用Tabs指令并遇到一些问题。

结构类似于:

//routes
$routeProvider..when('/course/:id', {
    controller: 'CourseCtrl',
    templateUrl: '/app/views/course.html'
});

//course.html
<div ng-controller="CourseTabsCtrl">
   <tabset>
      <tab>
         <tab-heading>Title</tab-heading>
         <div ng-include="'/view.html'"></div>
      </tab>
      ....
   </tabset>
</div>

问题是我无法访问api以启用或禁用标签,在所有控制器CourseTabsCtrlCourseCtrl中选择一个标签。

这是因为该指令正在处理隔离范围吗?如果有的话,有办法解决这个问题吗?我该如何解决?

由于

1 个答案:

答案 0 :(得分:2)

查看sourcedocumentation,您应该能够将表达式传递给<tab>指令,该指令指示它是启用还是禁用。

app.controller('CourseTabsCtrl', function ($scope) {
  $scope.expr = true;
});

<div ng-controller="CourseTabsCtrl">
 <tabset>
  <tab disabled="expr">
     <tab-heading>Title</tab-heading>
     <div ng-include="'/view.html'"></div>
  </tab>
  ....
 </tabset>
</div>

但是,如果这对你来说还不够。您可以'hack' tabset指令并使用另一个控制器而不是当前指定的控制器。现在,您必须复制默认TabSetController的旧行为,但您可以在其上添加功能以满足您的需求。

执行此操作的最佳方法({I})是decorate指令本身。

像这样:

app.config(function ($provide) {
  $provide.decorator('tabSetDirective', function ($delegate) {
    // $delegate in a directive decorator returns an array. The first index is the directive itself. 
    var dir = $delegate[0];

    dir.controller = 'CourseTabsController';

    return $delegate;
  });
});

您可以在此进一步构建并控制器传递给指令本身。

<tabset ctrl="someCustomCtrl"></tabset>

配置块将如下所示:

app.config(function ($provide) {
  $provide.decorator('tabSetDirective', function ($delegate) {
    // $delegate in a directive decorator returns an array. The first index is the directive itself. 
    var dir = $delegate[0];

    dir.controller = function ($scope, $element, $attrs, $controller) {
      return $controller($attrs.ctrl, {
        $scope: $scope
      });
    };

    return $delegate;
  });
});

注意:如果您使用装饰器方式,则可能必须在angular-ui模块的配置块中执行此操作。在这种情况下,您可能希望查看here,以便能够配置第三方模块而无需触及其核心代码。

传入控制器方式的第二个问题是,您需要使用$injector才能获得依赖关系($scope$element和{{1除外进入控制器。这可以在配置块中完成,也可以在控制器本身中通过添加$attrs作为依赖项来完成,如下所示:

$injector

我在谈论什么?

鉴于我没有亲自使用AngularUI Bootstrap组件,以及没有plunker / jsBin可用的事实,我在如何向第三方组件添加自定义行为方面抛出了一些技巧,而没有污染他们的核心代码。

要解决帖子末尾的问题:

  

这是因为该指令正在处理一个孤立的范围吗?

很可能,孤立范围的想法是不以其内在属性污染外部世界。因此,连接到 app.controller('CourseTabsController', function ($scope, $injector) { var $timeout = $injector.get('$timeout'); // etc... }); 指令API的唯一实时“端点”很可能是默认的AngularUI <tab>

  

......如果是的话,有办法解决这个问题吗?我该如何解决?

您可以执行我建议的操作并滚动您自己的控制器(请记住,您应首先重复来自TabSetController的代码),这样您应该已经完整访问TabSetController指令的端点。或者,在撰写本文时使用指令可用的选项,并等待引入更多功能。

我会尽快启动jsBin以进一步说明我的意思。

编辑:我们可以完成整个装饰者舞蹈和旧控制器行为的复制,而无需传入新的控制器。这就是我们如何实现这一目标:

<tab>

这是一个说明最后一个例子的jsBin:http://jsbin.com/hayulore/1/edit