Dynamically creating kendo-grid columns in angular controller

I am trying to dynamically build the structure of a kendo-angular grid. My problem is that the grid options are not known when the k-options attribute is evaluated, so the grid is binding to ALL of the columns on the datasource.

Here is the HTML:

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

And here is the javascript in the controller:

// 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()); 
}

The data is properly loading, but because gridModel.options was evaluated in the HTML prior to being set by the success method, it is essentially ignored and all of the columns from the datasource are being rendered.

This works like a champ when gridModel.options is static.

How can I defer the evaluation of k-options and/or force a reevaluation after they've been set by the controller?

I was able to figure it out. I had to do four things:

  1. Update my version of angularjs (I was on 1.08 which does not have the ng-if directive). I updated to 1.2.0rc3.
  2. Wrap my kendo-grid div in an ng-if div
  3. Invoke my function! I was just setting $scope.gridModel.options to a function - I needed to actually invoke the function so I'd be setting the variable to the value returned from the function.
  4. I had to update my angular.module declaration to include ngRoute (based on it being separated into it's own module in 1.2.x).

Here's the updated HTML:

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

And here's the updated controller (not shown: I set $scope.contentAvailable=false; at the beginning of the controller):

// 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
}

I actually moved the function into a config file so I'm not polluting the controller with too much configuration code. Very happy to have figured this out.

Here is a sample using 'Controller As' syntax, dynamic columns and paging.

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>