在角度控制器中动态创建kendo-grid列

时间:2013-10-14 15:40:47

标签: javascript angularjs kendo-ui kendo-grid

我正在尝试动态构建剑道角网格的结构。我的问题是,在评估k-options属性时,网格选项是未知的,因此网格绑定到数据源上的所有列。

这是HTML:

<div kendo-grid k-options="{{gridModel.options}}" 
    k-data-source="gridModel.myDataSource">
</div>

这是控制器中的javascript:

// this is called after the api call has successfully returned with data
function getSucceeded(){
    ...
    $scope.gridModel.options = function(){
        // function that properly builds options object with columns, etc.
    }
    // this is just shown for example... the data is properly loading
    $scope.gridModel.myDataSource.data(ds.data()); 
}

数据正在加载,但由于在成功方法设置之前在HTML中评估了gridModel.options,因此它基本上被忽略,并且正在呈现数据源中的所有列。

gridModel.options是静态的时,这就像一个冠军。

我如何推迟k-options的评估和/或在控制器设置后强制重新评估?

3 个答案:

答案 0 :(得分:7)

我能够弄清楚。我必须做四件事:

  1. 更新我的angularjs版本(我在1.08上没有ng-if指令)。我更新到1.2.0rc3。
  2. kendo-grid div换成ng-if div
  3. 调用我的功能!我只是将$scope.gridModel.options 设置为一个函数 - 我需要实际调用该函数,因此我将变量设置为函数返回的值。
  4. 我必须更新我的angular.module声明以包含ngRoute(基于它在1.2.x中被分成它自己的模块)。
  5. 这是更新后的HTML:

    <div data-ng-if="contentAvailable">
        <div kendo-grid k-options="{{gridModel.options}}" 
            k-data-source="gridModel.myDataSource">
        </div>
    </div>
    

    这是更新的控制器(未显示:我在控制器的开头设置$scope.contentAvailable=false;):

    // this is called after the api call has successfully returned with data
    function getSucceeded(){
        ...
        $scope.gridModel.options = function(){
            // function that dynamically builds options object with columns, etc.
        }(); // <----- NEED to invoke function!!
    
        // this is just shown for example... the data is properly loading
        $scope.gridModel.myDataSource.data(ds.data()); 
    
        $scope.contentAvailable=true; // trigger the ng-if
    }
    

    我实际上已将该函数移动到config文件中,因此我没有使用过多的配置代码来污染控制器。非常高兴能想到这一点。

答案 1 :(得分:2)

以下是使用“Controller As”语法,动态列和分页的示例。

var app = angular.module("app", ["kendo.directives"]);

function MyCtrl() {
  var colsList = [{
    name: "col1"
  }, {
    name: "col2"
  }, {
    name: "col3"
  }, {
    name: "col4"
  }];
  var gridCols = [];
  var iteration = 1;

  var vm = this;
  vm.gridOptions = {
    columns: gridCols,
    dataSource: new kendo.data.DataSource({
      pageSize: 10
    }),
    pageable: true
  };

  vm.buildGrid = function() {
    var data = {};

    vm.gridOptions.columns = [];
    for (var x = 0; x < colsList.length; x++) {
      if (iteration % 2 === 0 && x === colsList.length - 1) continue;

      var col = {};
      col.field = colsList[x].name;
      col.title = colsList[x].name;
      data[col.field] = "it " + iteration + " " + (1111 * (x + 1));
      vm.gridOptions.columns.push(col);
    }
    // add one row to the table
    vm.gridOptions.dataSource.add(data);
    iteration++;
  };
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<link rel="stylesheet" href="http://cdn.kendostatic.com/2015.1.318/styles/kendo.common.min.css" />
<link rel="stylesheet" href="http://cdn.kendostatic.com/2015.1.318/styles/kendo.default.min.css" />
<script src="http://cdn.kendostatic.com/2015.1.318/js/kendo.all.min.js"></script>

<body ng-app="app">

  <div ng-controller="MyCtrl as vm">
  <button ng-click="vm.buildGrid()">Build Grid</button>
  <div kendo-grid="grid" k-options="vm.gridOptions" k-rebind="vm.gridOptions"></div>
    </div>

</body>

答案 2 :(得分:0)

我们可以使用 k-rebind指令。来自文档:

Widget Update upon Option Changes

  

您可以从控制器更新小部件。使用特殊的k-rebind属性创建一个小部件,当某个范围变量发生更改时,该小部件会自动更新。此选项将销毁原始窗口小部件,并使用更改的选项重新创建它。

除了像往常一样在GridOptions中设置列数组外,我们还必须保留对它的引用:

        vm.gridOptions = { ... };
        vm.gridColumns = [{...}, ... ,{...}];
        vm.gridOptions.columns = vm.gridColumns;

然后将该变量传递给k-rebind指令:

        <div kendo-grid="vm.grid" options="vm.gridOptions" k-rebind="vm.gridColumns">
        </div>

当你将网格绑定到远程数据(在我的情况下是OData)时就是这样。现在,您可以在列数组中添加或删除元素。网格将在重新创建后再次查询数据。

当将Grid绑定到本地数据(本地对象数组)时,我们必须以某种方式推迟数据的绑定,直到重新创建窗口小部件。对我有用的(也许有一个更清晰的解决方案)是使用$ timeout服务:

        vm.gridColumns.push({ ... });

        vm.$timeout(function () {
            vm.gridOptions.dataSource.data(vm.myArrayOfObjects);
        }, 0);

已使用AngularJS v1.5.0和Kendo UI v2016.1.226对此进行了测试。