简体   繁体   English

angular-ui-router和angular-ui-bootstrap选项卡:内容多次加载到DOM中

[英]angular-ui-router and angular-ui-bootstrap tabs: content being loaded into DOM multiple times

I'm using angular-ui-bootstrap tabs and angular-ui-router. 我正在使用angular-ui-bootstrap 选项卡和angular-ui-router。 I want to load specific states into the tab-pane when a tab is clicked. 单击选项卡时,我想将特定状态加载到选项卡窗格中。 This is working fine. 一切正常。 The problem is that the state is being loaded into every tab pane in the DOM. 问题在于状态被加载到DOM中的每个选项卡窗格中。 Although the user can never tell, it is not a good idea to have all this content to be unnecessarily repeated in the DOM. 尽管用户永远不会说,但是让所有这些内容在DOM中不必要地重复并不是一个好主意。 The reason why this is happening is clear--the state templates are being inserted into ui-view, as can be seen below: 发生这种情况的原因很明显-状态模板已插入到ui-view中,如下所示:

<tabset>
  <tab class="clinical-tabs" ng-repeat="tab in tabs" heading="{{tab.title}}" active="tab.active" disabled="tab.disabled" ui-sref="activity.clinical.{{tab.title}}">
    <div ui-view></div>
  </tab>
</tabset>

And the result is that the content is being loaded in every tab-pane: 结果是在每个选项卡窗格中都加载了内容:

<div class="tab-content">
  <!-- ngRepeat: tab in tabs -->
  <div class="tab-pane ng-scope active" ng-repeat="tab in tabs" ng-class="{active: tab.active}" tab-content-transclude="tab">
    <!-- uiView:  -->
    <div ui-view="" class="ng-scope">
      CONTENT IS LOADED HERE
    </div>
  </div>
  <!-- end ngRepeat: tab in tabs -->

  <div class="tab-pane ng-scope" ng-repeat="tab in tabs" ng-class="{active: tab.active}" tab-content-transclude="tab">
    <!-- uiView:  -->
    <div ui-view="" class="ng-scope">
      CONTENT IS ALSO LOADED HERE
    </div>
  </div>
  <!-- end ngRepeat: tab in tabs -->
  ...
  ...
  ...
</div>

Like I said, the cause of the problem is clear. 就像我说的那样,问题的原因很明显。 However, I don't have enough experience with Angular to know how to come up with a solution. 但是,我对Angular的经验不足,无法知道如何提出解决方案。

While I'm not familiar with this tab directive, if you're looking to just have the content only be loaded once, you can make use of ngRepeat 's $first special scoping variable, which is equal to true only for the first iteration. 虽然我对这个tab指令不熟悉,但是如果您只希望将内容加载一次,则可以使用ngRepeat$first特殊作用域变量,该变量仅在第一次迭代时才等于true

Combine that with ngIf and you'd have the following: 将其与ngIf结合使用,您将获得以下内容:

<tabset>
  <tab class="clinical-tabs" ng-repeat="tab in tabs" heading="{{tab.title}}" active="tab.active" disabled="tab.disabled" ui-sref="activity.clinical.{{tab.title}}">
    <div ng-if="$first" ui-view></div>
  </tab>
</tabset>

Which would produce: 会产生:

<div class="tab-content">
  <!-- ngRepeat: tab in tabs -->
  <div class="tab-pane ng-scope active" ng-repeat="tab in tabs" ng-class="{active: tab.active}" tab-content-transclude="tab">
    <!-- uiView:  -->
    <div ui-view="" class="ng-scope">
      CONTENT IS LOADED HERE
    </div>
  </div>
  <!-- end ngRepeat: tab in tabs -->

  <div class="tab-pane ng-scope" ng-repeat="tab in tabs" ng-class="{active: tab.active}" tab-content-transclude="tab">
  </div>
  <!-- end ngRepeat: tab in tabs -->
  ...
  ...
  ...
</div>

I've found a solution. 我找到了解决方案。 The trick is to use multiple named views with ui-router 诀窍是在ui-router中使用多个命名视图

The HTML code should be changed such that the ui-view is now named (note ui-sref no longer needed): 应当更改HTML代码,以便现在命名ui视图(注意,不再需要ui-sref):

<tabset>
  <tab class="clinical-tabs" ng-repeat="tab in tabs" heading="{{tab.title}}" active="tab.active">
    <div ui-view="{{tab.title}}"></div>
  </tab>
</tabset>

In the main module, the $stateProvider should be configured differently There is a nice tutorial for setting up the multiple named views with ui-router here . 在主模块中,$ stateProvider应配置不同有一个很好的教程与UI的路由器设置了多个命名视图这里 The structure should be similar to: 结构应类似于:

.state('[parent]', {
  url: '/[someurl]',
  views: {
    '': { //<--this is the main template
      templateUrl: 'views/[view].html',
      controller: '[controller]'
    },
    '[child]@[parent]': { //<--these are the nested, named views that correspond to each tab
      templateUrl: 'views/[view].html',
      controller: '[controller]'
    },
    '...

Now, instead of one template being injected into the DOM 5 times (for 5 tabs), each template will be injected into its correct ui-view so there are no duplicates. 现在,不是将一个模板注入DOM 5次(用于5个选项卡),而是将每个模板注入其正确的ui视图中,因此没有重复项。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM