如何有效地重用部分?

时间:2013-07-28 19:42:40

标签: angularjs

我开始遇到很多这个问题。场景是我有一部分我想重用。问题是,我必须覆盖范围中的先前数据,以便新数据显示在部分中。我想知道人们如何解决这个问题。

以下是一个例子:

我有标签,都使用$scope.pebbles并共享相同的部分。对于每个选项卡,我希望填充不同的数据。很自然地,我只是对数据发出新请求并将其存储回变量以更改数据,例如:$scope.pebbles = getPebbles(color)。这个问题是我每次更改标签时都必须提出新的请求。如果有一个更好的方法没有一个巨大的部分吗?

overview.html:

<tab>
    <tab-heading>
        <i class="icon-bell"></i> All
    </tab-heading>
    <div class="tab-content">
        <div ng-include="'views/partials/_pebbles.html'"></div>
    </div>
</tab>
<tab ng-repeat="color in colors">
    <tab-heading ng-click="tab(color)">
        {{color}} 
    </tab-heading>
    <div class="tab-content"> 
        <div ng-include="'views/partials/_pebbles.html'"></div>
    </div>
</tab>

_pebbles.html:

 <table class="table table-striped table-bordered bootstrap-datatable datatable">
    <thead>
        <tr>
            <th>Pebble Name</th>
            <th>Pebble Type</th>
        </tr>
    </thead>   
    <tbody>
        <tr ng-repeat="pebble in pebbles">
            <td>{{pebble.name}}</td>
            <td>{{pebble.type}}</td>
        </tr>
    </tbody>
</table>

控制器:

$scope.colors = ['blue','red','orange','purple']
$scope.pebbles = getPebbles() // http factory, makes a request for data

$scope.tab = function (color) {
    $scope.pebbles = getPebbles(color)
}

4 个答案:

答案 0 :(得分:2)

一些简单的运行时缓存可以帮助您:

控制器:

$scope.colors = ['blue','red','orange','purple']
// $scope.pebbles = getPebbles(); // http factory, makes a request for data
$scope.pebbles = [];

$scope.tab = function (color) {
  $scope.selectedColor = color;
  $scope.pebbles[color] = $scope.pebbles[color] || getPebbles(color);
}

模板:

<table class="table table-striped table-bordered bootstrap-datatable datatable">
  <thead>
    <tr>
      <th>Pebble Name</th>
      <th>Pebble Type</th>
    </tr>
  </thead>   
  <tbody>
    <tr ng-repeat="pebble in pebbles[selectedColor]">
      <td>{{pebble.name}}</td>
      <td>{{pebble.type}}</td>
    </tr>
  </tbody>
</table>

答案 1 :(得分:2)

在角度世界中,跨控制器/视图共享数据的方式是使用服务。它们在控制器之间存在。

我准备写一个很好的答案,但我认为这个问题的答案已经完成了。

Better design for passing data to other ng-view's and persisting it across controllers

答案 2 :(得分:0)

Stewie的回答有效地完成了工作,但我想提出另一种你可能会使用的设计。

现在,您的控制器似乎混淆了两个问题;管理您的颜色(标签),以及管理给定颜色的鹅卵石(标签内容)。

你可以做的是拥有两个控制器,每个控制器管理其中一个问题。这使您可以让控制器具有明确的切割角色,并使控制器保持纤薄。从长远来看,它会在您向控制器添加更多功能时保持代码的可维护性。这是一个plunker,我创建了overviewController(处理标签管理)和pebblesController(处理单个标签内容)。

http://plnkr.co/edit/1ZP92VX0RljrsrfPpt0X?p=preview
**我伪造了服务器端getPebbles() http请求并创建了“平面”标签,因为我不想打扰制作实际的标签。

此实施需要注意的事项;动态标签加载变得更加困难(只有在第一次切换时才有标签内容加载),Stewie的运行时缓存示例处理得非常好。在我的plunker中,所有标签内容都是预先加载的。如果你想保留这个设计模式并加载动态标签,那么在tabs指令本身中支持它可能是最干净的,但这超出了这个问题的范围。

答案 3 :(得分:0)

所以我猜你正在使用Angular's UI-Bootstrap来建模标签。

正如Stewie建议您可以使用简单的缓存来缓存已加载的标签,据我所知,您希望在用户激活它们时按需加载标签。

查看我做过的小Plunkr,这正是如此。我已经使用select表达式来加载来自缓存或后端的变量选项卡。

主代码位于控制器中:

app.controller('PebblesCtrl', function ($scope, $http) {

  $scope.colors = ['blue', 'red', 'orange', 'purple'];
  $scope.pebbles = [];

  $scope.loadPebbles = function (color) {
    if (!$scope.pebbles[color]) {
      console.log('loading "' + color + '" pebbles');
      $http.get(color + '.json').then(function (response) {
        $scope.pebbles[color] = response.data;
      });
    }
  };
});

您还可以显示内容的占位符

<tab ng-repeat="color in colors" heading="{{color}}" select="loadPebbles(color)">     
  <div ng-show="pebbles[color]">
    <div ng-include="'_pebbles.html'"></div>
  </div>
  <div ng-hide="pebbles[color]">
    Please Wait...
  </div>
</tab>

当从服务返回数据时,它将被替换。