Angularjs 包装angular ui tabset指令并遇到;要求转换/隔离范围的多个指令”;错误

Angularjs 包装angular ui tabset指令并遇到;要求转换/隔离范围的多个指令”;错误,angularjs,angularjs-directive,angular-ui,angular-ui-bootstrap,Angularjs,Angularjs Directive,Angular Ui,Angular Ui Bootstrap,我试图扩展angular ui选项卡集功能,但在包装它时遇到了问题 此plunker是未包装的tabset指令: 此plunker包含我第一次尝试包装tabset指令: 最初的包装方法是直接包装。但是我在替换模板中引入了额外的div,以避免“多个指令要求隔离范围”和“多个指令要求转换”角度错误,并确保转换发生 关键代码片段: .directive('urlTabset', function() { return { restrict: 'E', transclude: t

我试图扩展angular ui选项卡集功能,但在包装它时遇到了问题

此plunker是未包装的tabset指令:

此plunker包含我第一次尝试包装tabset指令:

最初的包装方法是直接包装。但是我在替换模板中引入了额外的div,以避免“多个指令要求隔离范围”和“多个指令要求转换”角度错误,并确保转换发生

关键代码片段:

.directive('urlTabset', function() {
  return {
    restrict: 'E',
    transclude: true,
    replace: true,
    scope: {
      tabManager: '='
    },
    controller: [ "$scope", function($scope) {
      var tabManager = $scope.tabManager;
    }],
    template:
      '<div>' +
        '<tabset>' +
          '<div ng-transclude>' +
          '</div>' +
        '</tabset>' +
      '</div>'
  };
})

.directive('urlTab', function() {
  return {
    require: '^urlTabset',
    restrict: 'E',
    transclude: true,
    replace: true,
    scope: { tabName: '@' },
    link: function(scope, element, attrs, urlTabsetCtrl) {
    },
    template:
      '<div>' +
        '<tab>' +
          '<div ng-transclude>' +
          '</div>' +                  
        '</tab>' +
      '</div>'
  };
});
.directive('urlTabset',function(){
返回{
限制:'E',
是的,
替换:正确,
范围:{
选项卡管理器:'='
},
控制器:[“$scope”,函数($scope){
var tabManager=$scope.tabManager;
}],
模板:
'' +
'' +
'' +
'' +
'' +
''
};
})
.directive('urlTab',function(){
返回{
要求:“^urlTabset”,
限制:'E',
是的,
替换:正确,
作用域:{tabName:'@'},
链接:函数(作用域、元素、属性、urlTabsetCtrl){
},
模板:
'' +
'' +
'' +
'' +                  
'' +
''
};
});
但是,我认为模板中额外的div会导致问题。这是一个展开的选项卡集,在我的模板将添加它们的地方有额外的div

所以合乎逻辑的事情是消除div。。。但这就是我需要帮助的地方。有没有人知道一种干净的方法可以做到这一点,而不会碰到“要求隔离范围的多个指令”和“要求转换的多个指令”的角度错误。这是一次失败的尝试

错误:多个指令[urlTab,tab]请求对以下项进行转换:
顺便说一句,如果您想知道我想做什么,我的最终目标是使用传递给urlTabset的tabManager属性来自动填充tab指令中的字段(由urlTab包装)。更具体地说,这是我的目标:

.directive('urlTab', function() {
  return {
    require: '^urlTabset',
    restrict: 'E',
    transclude: true,
    replace: true,
    scope: { tabName: '@' },
    link: function(scope, element, attrs, urlTabsetCtrl) {
      scope.tabs = urlTabsetCtrl.tabs;
      scope.tabSelected = urlTabsetCtrl.tabSelected;
    },
    template:
      '<tab active="tabs[tabName].active" disabled="tabs[tabName].disabled" select="tabSelected(tabName)" ng-transclude>' +
      '</tab>'
  };
});
.directive('urlTab',function(){
返回{
要求:“^urlTabset”,
限制:'E',
是的,
替换:正确,
作用域:{tabName:'@'},
链接:函数(作用域、元素、属性、urlTabsetCtrl){
scope.tabs=urlTabsetCtrl.tabs;
scope.tabSelected=urlTabsetCtrl.tabSelected;
},
模板:
'' +
''
};
});
上面的模板显然不起作用,但它为您提供了我试图做的要点


我同意一个解决方案,它要求wrapping指令没有一个单独的作用域。我可以通过在控制器上下文中存储状态来解决这个问题。

如果您试图增强
angular ui
的功能,最好使用属性指令,而不是全新的元素。我可能弄错了,但看起来您不打算改变DOM的一般结构,而只是用angular ui的指令替换您的指令。例如,使用HTML

<tabset url-tabset>
    <tab url-tab>
        <tab-heading>
            <i class="icon-list"></i> Details
        </tab-heading>
        Details content.
    </tab>
    <tab url-tab>
        <tab-heading>
            <i class="icon-thumbs-up"></i> Impact
        </tab-heading>
        Impact tab content.
    </tab>                    
</tabset>

首先感谢您的回复。我很感激。我的plunker是从我想做的事情简化而来的,即使用tabManager状态(在urlTabset中指定)来自动填充tab指令中的属性(由urlTab包装)。所以这不是一个严格的扩充。这意味着这种方法对我不起作用。还有其他想法吗?我想如果只是添加属性,你可以通过
attrs
而不是使用模板。只要您的指令与您希望更改的指令位于同一元素上。您建议在编译阶段添加属性,这样当wrapped指令在其compile/link函数中处理它们时,它就会看到它们。但这不会处理包装指令隔离范围内的变量,比如tab的“select”。或者,既然已经订购了编译,那么所有这些都将得到解决。不过还是有点粗糙。我不想做这种事。我想要真正的包装,使html看起来干净。但我感谢你的努力/想法分享。我希望有一种简单的方法来实现干净的包装。对于表达式属性,您仍然可以在编译阶段添加表达式,但是您需要将范围变量添加到父范围中,我同意这是一种非常粗糙的方法。理想情况下,
选项卡集
选项卡
控制器将从您的指令中公开要使用的函数(如使用
ngModel
),但此时您真正能做的就是
tabsetCtrl。选择
或可能的
。添加选项卡
。删除选项卡
。基本上,如果你想用有角度的ui指令替换你的指令,你俩将使用相同的作用域,并且你们中只有一个人能够转移或要求隔离。感谢赏金@Amir!遗憾的是,没有人能够提供一个更简单/不那么凌乱的设计。
<tabset url-tabset>
    <tab url-tab>
        <tab-heading>
            <i class="icon-list"></i> Details
        </tab-heading>
        Details content.
    </tab>
    <tab url-tab>
        <tab-heading>
            <i class="icon-thumbs-up"></i> Impact
        </tab-heading>
        Impact tab content.
    </tab>                    
</tabset>
angular.module('plunker', ['ui.bootstrap'])

.directive('urlTabset', function() {
  return {
    restrict: 'A',
    require: 'tabset', // Confirm the directive is only being used on tabsets
    controller: [ "$scope", "$attrs", function($scope, $attrs) {
      var tabManagerGetter = $parse($attrs.tabManager); // '='
      this.getTabManager = function() {
        return tabManagerGetter($scope);
      };

      // fun stuff here
    }]
  };
})

.directive('urlTab', function() {
  return {
    require: ['tab', '^urlTabset'],
    restrict: 'A',
    link: function(scope, element, attrs, ctrls) {
      var urlTabsetCtrl = ctrls[1];

      function getTabName() {
        return attrs.tabName; // '@'
      }

      var tabManager = urlTabsetCtrl.getTabManager();

      // fun stuff here
    }
  };
});