【问题标题】:Tabs directive with Angular带有 Angular 的选项卡指令
【发布时间】:2015-11-11 16:43:27
【问题描述】:

我正在创建一个 Angular 选项卡指令,应用如下:

<div id="tabs-with-directive" data-tabs>      
  <ul class="tabs">
    <li><a href="#" data-tabs-link="1">One</a></li>
    <li><a href="#" data-tabs-link="2">Two</a></li>
  </ul>            
  <div class="panes">
    <div data-tabs-pane="1" class="pane active">One</div>
    <div data-tabs-pane="2" class="pane">Two</div>
  </div>
</div>  

所以点击一个会显示窗格一,点击二会显示第二个窗格,...

我创建了一个有效的Plunker example without using a directive

我有一个Plunker example using the directive I am trying to build

angular.module("app", [tabs]);   

(function(angular) {

  'use strict';

  angular.module('tabs', []);

  angular.module('tabs')
    .directive('tabs', tabsDirective);

  function tabsDirective() {
    return {
        scope: true,
        restrict: 'A',
        controller: tabsController
    };
  }

  function tabsController($scope) {

    $scope.tabs = [];

    this.addTab = function (tab) {
        $scope.tabs.push(tab);
    };

    this.isTabActive = function (link) {
      for(var i = 0; i < $scope.tabs.length; i++) {
        if ($scope.tabs[i].link == link)
          return $scope.tabs[i].active;
      }
      return false;
    };

    this.setTabToActive = function (link) {
      for(var i = 0; i < $scope.tabs.length; i++) 
        $scope.tabs[i].active = $scope.tabs[i].link == link;
    };        

  }

  tabsController.$inject = ['$scope'];

  angular.module('tabs')
    .directive('tabsLink', tabsLinkDirective);

  function tabsLinkDirective() {
    return {
        scope: false,
        restrict: 'A',
        require: '^tabs',
        link: function (scope, element, attributes, controller) {

          var tab = { link: attributes.link, active: "false" };
          controller.addTab(tab);

          element.bind('click', function () {
            controller.setTabToActive(attributes.link);
          });

          scope.$watch('tabs', function () {
            element.toggleClass('active', controller.isTabActive(attributes.link));
          });

        }
    };
  }

  angular.module('tabs')
    .directive('tabsPane', tabsPaneDirective);

  function tabsPaneDirective() {
    return {
        scope: false,
        restrict: 'A',
        require: '^tabs',
        link: function (scope, element, attributes, controller) {

            scope.$watch('tabs', function () {
              element.toggleClass('active', controller.isTabActive(attributes.pane));
            });

        }
    };
  }

})(angular);

不幸的是,这不起作用,我找不到我做错了什么。

有人可以帮帮我吗?

【问题讨论】:

  • 这对你有用吗?

标签: angularjs


【解决方案1】:

默认情况下,$watch 比较引用是否相等。由于您正在修改数组中的对象,因此数组引用将保持不变,并且不会触发监视侦听器。

要查看对数组中对象的修改,您需要将true 作为第三个参数传递:

scope.$watch('tabs', function() {
  element.toggleClass('active', controller.isTabActive(tab.link));
}, true);

以下内容:

attributes.link

应在所有地方替换为以下内容:

attributes.tabsLink

还有以下内容:

attributes.pane

应替换为:

attributes.tabsPane

我假设您希望其中一个选项卡启动时处于活动状态。

您拥有的以下内容将不起作用:

class="pane active"

由于没有一个选项卡模型将active 设置为true,因此以下代码将删除active 类:

scope.$watch('tabs', function() {
  element.toggleClass('active', controller.isTabActive(attributes.tabsPane));
}, true);

如果您希望 active 类指示选项卡是否应以活动状态启动,您可以添加如下内容:

if (element.hasClass('active')) {
  controller.setTabToActive(attributes.tabsPane);
}

请注意,这不会阻止多个选项卡启动为活动状态,如果没有一个选项卡具有该类,它也不会将一个选项卡设置为活动状态。


我强烈建议更改:

active: "false"

收件人:

active: false

并改为使用严格相等(=== 而不是==


element.on 不是 AngularJS 函数,不会为您触发摘要循环 - 这意味着数据绑定不会在 UI 中更新。

您需要手动完成:

element.bind('click', function() {
  scope.$apply(function() {
    controller.setTabToActive(tab.link);
  });
});

演示: http://plnkr.co/edit/9nskxIR0DHaDuAEG9CfX?p=preview

【讨论】:

  • 对不起,完全错过了你的答案......它工作得很好。感谢您的帮助。我刚刚标记为答案。
猜你喜欢
  • 2018-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多