嵌套的JqueryUI选项卡作为Angular指令 - 不匹配的片段标识符

时间:2014-06-23 06:43:32

标签: jquery angularjs angularjs-directive jquery-ui-tabs

我尝试创建 mastertab 。这个mastertab拥有n个面板。每个面板都包含子选项卡,还包含多个面板。子选项卡的选项卡ID动态独特。构造按预期呈现,但是当我单击非活动子选项卡面板时,我收到此错误

  

未捕获错误:jQuery UI选项卡:不匹配的片段标识符。

我做了 fiddle

HTML to' start' mastertab

<div ng-app="myApp">
    <div master-tab></div>
</div>

mastertab指令

myApp.directive('masterTab', function () {
    return {
        restrict: 'A',
        template: '<div id="mstrtab"><ul><li><a href="#master-tab1">Mst 1</a></li><li><a href="#master-tab2">Mst 2</a></li><li><a href="#master-tab3">Mst 3</a></li></ul><div id="master-tab1"><p>master panel 1<div sub-tab="Foo"></div></p></div><div id="master-tab2"><p>master panel 2<div sub-tab="BAR"></div></p></div><div id="master-tab3"><p>master panel 3</p></div></div>',
        link: function (scope, element, attrs) {
            element.tabs();
        }
    }
});

注意我给subtabs一个参数:

<div sub-tab="BAR">

这是subtab指令:

myApp.directive('subTab', function () {
    return {
        restrict: 'A',
        scope: true,
        template: '<div id="subTab{{tabLetter}}"><ul><li><a href="#sub-tabs1{{tabLetter}}">SubTab1{{tabLetter}}</a></li><li><a href="#sub-tabs2{{tabLetter}}">SubTab2{{tabLetter}}</a></li><li><a href="#sub-tabs3{{tabLetter}}">SubTab3{{tabLetter}}</a></li></ul><div id="sub-tabs1{{tabLetter}}"><p>SubTab {{tabLetter}} 1</p></div><div id="sub-tabs2{{tabLetter}}"><p>SubTab {{tabLetter}} 2.</p></div><div id="sub-tabs3{{tabLetter}}"><p>SubTab {{tabLetter}} 3.</p></div></div>',

        link: function (scope, element, attrs) {
            scope.tabLetter = attrs.subTab;
            console.log(attrs.subTab);
            element.tabs();
        }
    }
});

我认为它与Angular中的渲染顺序有关,但我不确定。检查呈现的HTML源代码表明,有时可能无法呈现{{tabLetter}},但在演示文稿中所有内容似乎都可以。底层的javascript对象似乎也有正确的和预期的名称......

有人可以帮我解决这个难题吗?我如何使这个工作?

1 个答案:

答案 0 :(得分:0)

在链接函数中初始化element.tabs()插件时,角色表达式subTab{{tabLetter}}尚未呈现。

要解决此问题,您可以使用$ timeout服务:

myApp.directive('subTab', function ($timeout) {
    return {
        restrict: 'A',
        scope: true,
        template: '<div id="subTab{{tabLetter}}"><ul><li><a href="#sub-tabs1{{tabLetter}}">SubTab1{{tabLetter}}</a></li><li><a href="#sub-tabs2{{tabLetter}}">SubTab2{{tabLetter}}</a></li><li><a href="#sub-tabs3{{tabLetter}}">SubTab3{{tabLetter}}</a></li></ul><div id="sub-tabs1{{tabLetter}}"><p>SubTab {{tabLetter}} 1</p></div><div id="sub-tabs2{{tabLetter}}"><p>SubTab {{tabLetter}} 2.</p></div><div id="sub-tabs3{{tabLetter}}"><p>SubTab {{tabLetter}} 3.</p></div></div>',

        link: function (scope, element, attrs) {
            scope.tabLetter = attrs.subTab;
            console.log(attrs.subTab);

            $timeout(function() {
                element.tabs();
            }, 0);
        }
    }
});

<强> [编辑] 上述解决方案有效,因为它确保在浏览器呈现后发生.tabs插件初始化。

另一种方法是使用$ watch并为其提供$ watch处理程序。此解决方案也有效,因为在浏览器呈现视图后调用$ watch处理程序:

link: function (scope, element, attrs) {
    scope.tabLetter = attrs.subTab;
    console.log(attrs.subTab);
    scope.$watch('tabLetter', function(newVal) {
        var val = newVal || null;  
        if (newVal) {
           element.tabs();
        }

    });
}