Angular UI Bootstrap Tabset:阻止选项卡切换

时间:2014-12-23 13:43:58

标签: angularjs twitter-bootstrap tabs angular-ui-router

我遇到问题,试图阻止标签切换。 这是掠夺者。 http://plnkr.co/edit/v1i1cmBzqGo7hmWkhIh4?p=preview 当用户单击“警报”选项卡时,我想进行一些条件测试,并防止未选中“警报”选项卡。 我怎样才能做到这一点? 另一个问题是每个标签与ui状态相关联。 当选项卡被更改时,ui状态也在变化。 我想阻止它,我制作了这段代码。

$rootScope.$on('$stateChangeStart',
        function(event, toState, toParams, fromState, fromParams){
          event.preventDefault();

          destinationTab.active = false;
          sourceTab.active = true;
        });

然后在此代码之后,原始选项卡不活动。

1 个答案:

答案 0 :(得分:0)

我也遇到过这个问题并写了一个小指令来修复它。这是超级hacky,但基本上它寻找所有标签标题链接,添加点击事件,翻转每个链接的事件顺序以使我们的事件在角度之前触发,然后使用promises允许控制器方法来控制标签切换。这也应该与他们的select / deselect属性一起使用。

指令:

.directive('tabPrevent', ['$q', '$timeout', function ($q, $timeout) {
    'use strict';

    return {
        restrict: 'A',
        link: function (scope, element, attrs) {
            var tabHeadings = element.find('ul li a'),
                  tabEvents = [];

            if (attrs.tabPrevent) {
                tabHeadings.bind('click', function (e) {
                    e.stopImmediatePropagation();

                    var deferred = $q.defer(),
                          self = this,
                          tabIndex = -1

                    // find tab index for tabEvents reference
                    angular.forEach(tabHeadings, function (tab, index) {
                        if (tab === self) {
                            tabIndex = index;
                        }
                    });

                    // call controller method, passing promise
                    scope.$eval(attrs.tabPrevent + '(deferred)', { deferred: deferred });

                    deferred.promise.then(function (success) {
                        // initiate call to next event in array, which switches the tab
                        $timeout(function() {
                            tabEvents[tabIndex].click[1].handler(e);
                        });
                    });
                });

                // flip event order to make our event fire before angular's
                angular.forEach(tabHeadings, function (tabHeading) {
                    var clickEvents = $._data(tabHeading, "events");
                    tabEvents.push(clickEvents);    // save list of click events
                    clickEvents.click.unshift(clickEvents.click.pop()); // reverse events
                });
            }
        }
    };

}]);

HTML:

        <tabset tab-prevent="checkTab">
            <tab heading="{{tabs[0].title}}" active="tabs[0].active">Tab 1</tab>
            <tab heading="{{tabs[1].title}}" active="tabs[1].active">Tab 2</tab>
            <tab heading="{{tabs[2].title}}" active="tabs[2].active">Tab 3</tab>
        </tabset>

控制器:

    $scope.checkTab = function (deferred) {
        if ($scope.form && $scope.form.$dirty) {
            deferred.reject();  // stops tab switch
        } else {
            deferred.resolve();  // allows tab swtich
        }
    };