为什么动态创建可切换选项卡会在AngularJS中div时导致重复?

为什么动态创建可切换选项卡会在AngularJS中div时导致重复?,angularjs,tabs,twitter-bootstrap-3,dynamically-generated,Angularjs,Tabs,Twitter Bootstrap 3,Dynamically Generated,我使用Bootstrap和AngularJS在HTML中动态创建可单击的选项卡。更具体地说,我使用ng开关和ng开关when指令来控制在任何给定时间显示哪个选项卡的内容 请注意:下面您会注意到我使用了一个控制器来进行DOM操作。我意识到执行DOM操作的“AngularJS方式”是使用指令(而不是控制器)。我不是故意违反好的编码实践的人,但是既然我在尝试了解控制器和指令时遇到的这个问题,我想请你现在只考虑使用一个控制器,因为我相信这可能是这个问题的原因。 如果你继续阅读,你会注意到我已经找到了一个

我使用Bootstrap和AngularJS在HTML中动态创建可单击的选项卡。更具体地说,我使用
ng开关
ng开关when
指令来控制在任何给定时间显示哪个选项卡的内容

请注意:下面您会注意到我使用了一个控制器来进行DOM操作。我意识到执行DOM操作的“AngularJS方式”是使用指令(而不是控制器)。我不是故意违反好的编码实践的人,但是既然我在尝试了解控制器和指令时遇到的这个问题,我想请你现在只考虑使用一个控制器,因为我相信这可能是这个问题的原因。 如果你继续阅读,你会注意到我已经找到了一个基于指令的解决方案(即“AngularJS方式”),但我特别想问一下使用控制器和
ng开关时发生的问题

问题是: 我面临的问题如下。当我将
div
标记(包含
ng开关When
指令)附加到容器上,然后使用
$compile
编译这些标记时,每个标记的内容都会在
时使用
ng开关以某种方式重复。为了避免这个问题变得太长,我将代码预期行为的概念放在下面第一个JSFiddle的注释中,它演示了这个问题

--使用控制器进行DOM操作(“非AngularJS方式”),导致在
时使用
ng开关意外复制标记

关于如何复制副本的详细描述如下。创建新选项卡时,先前单击的选项卡内容(在
div
中,包含
ng开关,当
时)似乎是重复的。通过加载上述JSFIDLE,右键单击
默认值
文本,选择
检查元素
,然后在选项卡式窗格中按
分析>创建选项卡
,可以看到这种情况。您将看到,现在有两个
div
标记,其中
ng开关when=“Default”
,而不是只有一个。如果继续创建新选项卡,则此模式将继续用于
view1
view2
等。或者,只需单击
Analysis>Create Tab
5次,然后查看选项卡1-4中的重复项。无论哪种方式,只要创建一个新选项卡,您都会看到以前选择的选项卡的内容加倍

由于对这种意外行为感到失望,我继续使用为选项卡组件创建自定义指令的方法实现了一个基于指令的解决方案,以获得所需的功能

--使用DOM操作指令(“AngularJS方式”)

然而,正如我所提到的,我想知道为什么我的第一个JSFIDLE不能工作。正式问题见下文

需要考虑的要点:
  • 问题可能与范围、脚本加载顺序或逻辑错误有关
  • 也许这是AngularJS根本做不到的。我知道,这个问题可能与此有关
因此,我的问题如下: 为什么会发生这种重复?是否有办法防止/解决创建重复项的问题?记住,我不会在实践中使用它,我只是好奇这个问题是否能解决

请注意:我不希望使用jQuery解决此问题,例如。虽然我知道AngularJS使用了一个更轻版本的jQuery,称为jqLite-undertheHood,但我正在寻找一个“纯AngularJS”的解决方案

HTML:

<!-- Include CDNs (see JSFiddle above) -->
<!-- Wrap in HTML tags, include DOCTYPE -->
<body ng-app="myApp">
    <div class="panel panel-default" ng-controller="myCtrl">
        <div class="panel-heading">
            <ul class="nav nav-tabs">
                <li class="active">
                    <a class="h4">My App</a>
                </li>
                <li class="dropdown">
                    <a href="" class="dropdown-toggle h4" data-toggle="dropdown">
                        Analysis
                        <span class="caret"></span>
                    </a>
                    <ul class="dropdown-menu">
                        <li>
                            <button id="createTabLink" class="h4" ng-click="createTabClick()">Create Tab</button>
                        </li>
                    </ul>
                </li>
            </ul>
        </div>
        <div class="panel-body">
            <div class="panel panel-default">
                <div class="panel-heading">
                    <ul id="createTabDiv" class="nav nav-tabs"></ul>
                </div>
                <div class="panel-body">
                    <div id="viewWrapper" ng-switch="" on="viewSelected">
                        <div id="Default" ng-switch-when="Default">Default</div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</body>
angular.module('myApp', []);

function myCtrl($scope, $compile) {
    $scope.count = 0;
    $scope.viewSelected = "Default";

    $scope.tabClick = function($event) {
        var tab = $event.target;
        var viewName = tab.getAttribute("value");
        $scope.viewSelected = viewName;
    };

    $scope.createTabClick = function() {
        $scope.count++;
        var viewName = "view" + $scope.count;
        var createTabDiv = angular.element(document.querySelector('#createTabDiv'));
        var viewWrapper = angular.element(document.querySelector('#viewWrapper'));
    
        var $comp1 = createTabDiv.append('<li class="active"><a class="h4" value="' + viewName + '" ng-click="tabClick($event)">Tab ' + $scope.count + '</a></li>');
        $compile($comp1)($scope);
        var $comp2 = viewWrapper.append('<div id="' + viewName + '" ng-switch-when="' + viewName + '">' + viewName + '</div>');
        $compile($comp2)($scope);
    
        $scope.viewSelected = viewName;
    };
}

    • 创建选项卡
    违约
    JS:

    <!-- Include CDNs (see JSFiddle above) -->
    <!-- Wrap in HTML tags, include DOCTYPE -->
    <body ng-app="myApp">
        <div class="panel panel-default" ng-controller="myCtrl">
            <div class="panel-heading">
                <ul class="nav nav-tabs">
                    <li class="active">
                        <a class="h4">My App</a>
                    </li>
                    <li class="dropdown">
                        <a href="" class="dropdown-toggle h4" data-toggle="dropdown">
                            Analysis
                            <span class="caret"></span>
                        </a>
                        <ul class="dropdown-menu">
                            <li>
                                <button id="createTabLink" class="h4" ng-click="createTabClick()">Create Tab</button>
                            </li>
                        </ul>
                    </li>
                </ul>
            </div>
            <div class="panel-body">
                <div class="panel panel-default">
                    <div class="panel-heading">
                        <ul id="createTabDiv" class="nav nav-tabs"></ul>
                    </div>
                    <div class="panel-body">
                        <div id="viewWrapper" ng-switch="" on="viewSelected">
                            <div id="Default" ng-switch-when="Default">Default</div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </body>
    
    angular.module('myApp', []);
    
    function myCtrl($scope, $compile) {
        $scope.count = 0;
        $scope.viewSelected = "Default";
    
        $scope.tabClick = function($event) {
            var tab = $event.target;
            var viewName = tab.getAttribute("value");
            $scope.viewSelected = viewName;
        };
    
        $scope.createTabClick = function() {
            $scope.count++;
            var viewName = "view" + $scope.count;
            var createTabDiv = angular.element(document.querySelector('#createTabDiv'));
            var viewWrapper = angular.element(document.querySelector('#viewWrapper'));
        
            var $comp1 = createTabDiv.append('<li class="active"><a class="h4" value="' + viewName + '" ng-click="tabClick($event)">Tab ' + $scope.count + '</a></li>');
            $compile($comp1)($scope);
            var $comp2 = viewWrapper.append('<div id="' + viewName + '" ng-switch-when="' + viewName + '">' + viewName + '</div>');
            $compile($comp2)($scope);
        
            $scope.viewSelected = viewName;
        };
    }
    
    angular.module('myApp',[]);
    函数myCtrl($scope$compile){
    $scope.count=0;
    $scope.viewSelected=“默认”;
    $scope.tabClick=函数($event){
    var选项卡=$event.target;
    var viewName=tab.getAttribute(“值”);
    $scope.viewSelected=viewName;
    };
    $scope.createTabClick=function(){
    $scope.count++;
    var viewName=“view”+$scope.count;
    var createTabDiv=angular.element(document.querySelector(“#createTabDiv”);
    var viewWrapper=angular.element(document.querySelector(“#viewWrapper”);
    var$comp1=createTabDiv.append('
  • Tab'+$scope.count+'
  • '); $compile($comp1)($scope); var$comp2=viewWrapper.append(“”+viewName+“”); $compile($comp2)($scope); $scope.viewSelected=viewName; }; }