如何使用Angular UI选项卡和UI网格重绘表?

时间:2015-12-14 07:20:20

标签: angularjs angular-ui-bootstrap angular-ui angular-ui-grid

我尝试从jQuery数据表迁移到Angular UI。我的应用程序使用MySQL World schema并在3个不同的表中显示数据。在jQuery中,我有3个不同的页面,每个页面都是从主页启动的。这是live example。 在Angular中,我创建了3个选项卡,单击每个选项卡应该使用新网格重新加载页面并使用数据填充它。问题是,网格在页面加载时显示正常,第一个选项卡上的内容。单击其他选项卡时,页面变为空,并且不呈现任何内容。现在返回的数据并非无关紧要,有时约为4k行。但是,问题不是延迟问题,因为我已经等了几分钟确认了。

我不是JS / CSS / HTML的人,所以我很可能错过了什么。这就是为什么这个问题。

修改 Plnkr

以下是代码:

HTML:

<body>
<div id="selection-panel" class="selection-panel" ng-controller="HelloWorldCtrl">
    <div>
        <uib-tabset type="pills" justified="true">
            <uib-tab ng-repeat="tab in tabs" heading="{{tab.title}}" select="update(tab.title)">
                <div id="data-panel" class="data-panel" ui-grid="gridOptions"></div>
            </uib-tab>
        </uib-tabset>
    </div>
</div>
<script src="js/app.js"></script>
</body>

JS:

(function() {
    var app = angular.module('helloWorld', ['ui.bootstrap', 'ui.grid']);

    app.controller('HelloWorldCtrl', ['$http', '$scope', function ($http, $scope) {
        $scope.tabs = [
            { title: 'Countries' },
            { title: 'Cities' },
            { title: 'Languages' }
        ];

        $scope.gridOptions = {};
        $scope.gridOptions.data = [];

        $scope.gridOptionsCountries = {
            columnDefs: [
                { name: 'code'},
                { name: 'name'},
                { name: 'continent'},
                { name: 'region'},
                { name: 'population'}
            ]
        };

        $scope.gridOptionsCities = {
            columnDefs: [
                { name: 'id'},
                { name: 'name'},
                { name: 'country'},
                { name: 'population'}
            ]
        };

        $scope.gridOptionsLanguages = {
            columnDefs: [
                { name: 'country'},
                { name: 'language'}
            ]
        };

        $scope.update = function(title) {
            if (title === "Countries") {
                $scope.gridOptions = angular.copy($scope.gridOptionsCountries);
            } else if (title === "Cities") {
                $scope.gridOptions = angular.copy($scope.gridOptionsCities);
            } else if (title === "Languages") {
               $scope.gridOptions = angular.copy($scope.gridOptionsLanguages);
            }

            $http.get(title.toLowerCase()).success(function(data) {
                $scope.gridOptions.data = data;
            });
        };
    }]);
})();

3 个答案:

答案 0 :(得分:1)

我不能让它在标签中工作,我的猜测是因为你首先使用ng-repeat为每次迭代创建一个范围,然后标签本身可能会创建一个新的范围,这会引起很多令人头疼的更新

最快的解决方案就是将网格移到选项卡之外。

这是更新的html。

HTML

ordered = True

答案 1 :(得分:1)

我在这里看到两个问题:

  1. 您正在创建/更改gridOptions。这不是通常的做事方式,可能带来很多问题。

  2. 您正在使用uib-tabs内的网格,这与uib-modals一样,可能会产生一些烦人的副作用。

  3. 我建议您使用不同的gridOptions解决第一个问题(就像您创建它们时一样),然后将它们放入tabs数组子项中,这样您就可以参考了他们来自html这个whay:

    <uib-tab ng-repeat="tab in tabs" heading="{{tab.title}}" select="update(tab.title)">
      <div id="data-panel" class="data-panel" ui-grid="tab.gridOptions"></div>
    </uib-tab>
    

    第二个问题是众所周知的,在this教程中他们解释了如何解决它:你应该添加$interval指令刷新网格一段时间后按顺序更新让标签花时间加载和渲染。

    代码应如下:

    $scope.tabs[0].gridOptions.data = data; 
    $interval( function() {
      $scope.gridCountriesApi.core.handleWindowResize();
    }, 10, 500);
    

    在常规gridCountriesApi方法中创建onRegisterApi的位置。

    我修改了您的plunkr,因此您可以看到整个代码。

答案 2 :(得分:0)

在我的情况下,标签内容消耗了重要的加载时间。因此,如果您的情况是每次单击选项卡时都不想更新选项卡内容,则可以使用此解决方法:

在HTML部分中,我使用select属性来指示按下哪个选项卡:

<tabset justified="true">
    <tab heading="Tab 1" select="setFlag('showTab1')">
        <div ng-if="showTab1">
        ...
        </div>
    </tab>
</tabset>

在标签(*)容器中,我使用开关识别按下了哪个标签并广播了按下操作:

case 'showTab1':
    $scope.$broadcast('tab1Selected');
    break;

在控制器部分,我会监听事件并处理调整大小:

// The timeout 0 function ensures that the code is run zero milliseconds after angular has finished processing the document.
$scope.$on('tab1Selected', function () {

      $timeout(function() {

          $scope.gridApi1.core.handleWindowResize();
      }, 0);
});

这是我的Plunkr。希望它有所帮助。

(*)对于当前的bootstrap版本,您应该使用