bob.mazzo
bob.mazzo

Reputation: 5637

Adding a new data model to Malhar-Angular-Dashboard

Im' working on the Malhar Angular Dashboard, based on this github project https://github.com/DataTorrent/malhar-angular-dashboard.

As per the documentation in the link post just above, under the 'dataModelType' heading 1/2 way down:

`The best way to provide data to a widget is to specify a dataModelType in the Widget Definition Object (above). This function is used as a constructor whenever a new widget is instantiated on the page.`

And when setting up the Widget Definition Objects, there are various options to choose from :

templateUrl - URL of template to use for widget content

template - String template (ignored if templateUrl is present)

directive - HTML-injectable directive name (eg. "ng-show")

So when I add my own widget definition column chart, I attempt to use the 'template' option; however it does NOT inject the {{value}} scope variable I'm setting.

Using the original datamodel sample widget def, it works fine using the 'directive' option. If I mimic this method on my column chart definition then it works ! But it doesn't work using the template option.

Here's the 'widgetDefinitions' factory code :

  (function () {
'use strict';
angular.module('rage')
    .factory('widgetDefinitions', ['RandomDataModel','GadgetDataModel',  widgetDefinitions])

function widgetDefinitions(RandomDataModel, GadgetDataModel) {
    return [          
      {
          name: 'datamodel',
          directive: 'wt-scope-watch',
          dataAttrName: 'value',
          dataModelType: RandomDataModel    // GOTTA FIGURE THIS OUT !! -BM:
      },
      {
          name: 'column chart',
          title: 'Column Chart',
          template: '<div>Chart Gadget Here {{value}}</div>',            
          dataAttrName: 'value',  
          size: {width: '40%',height: '200px'},
          dataModelType: ColumnChartDataModel
      },
    ];
}       
 })();

and here are the factories:

'use strict';

angular.module('rage')
  .factory('TreeGridDataModel', function (WidgetDataModel, gadgetInitService) {
      function TreeGridDataModel() {
      }

      TreeGridDataModel.prototype = Object.create(WidgetDataModel.prototype);
      TreeGridDataModel.prototype.constructor = WidgetDataModel;

      angular.extend(TreeGridDataModel.prototype, {
          init: function () {
              var dataModelOptions = this.dataModelOptions;
              this.limit = (dataModelOptions && dataModelOptions.limit) ? dataModelOptions.limit : 100;
              this.treeGridActive = true;
              //this.treeGridOptions = {};
              this.updateScope('THIS IS A TreeGridDataModel...');  // see WidgetDataModel factory           
          },

          updateLimit: function (limit) {
              this.dataModelOptions = this.dataModelOptions ? this.dataModelOptions : {};
              this.dataModelOptions.limit = limit;
              this.limit = limit;
          },

          destroy: function () {
              WidgetDataModel.prototype.destroy.call(this);             
          }
      });

      return TreeGridDataModel;
  });

'use strict';

angular.module('rage')
  .factory('ColumnChartDataModel', function (WidgetDataModel) {
      function ColumnChartDataModel() {
      }

      ColumnChartDataModel.prototype = Object.create(WidgetDataModel.prototype);
      ColumnChartDataModel.prototype.constructor = WidgetDataModel;

      angular.extend(ColumnChartDataModel.prototype, {
          init: function () {
              var dataModelOptions = this.dataModelOptions;
              this.limit = (dataModelOptions && dataModelOptions.limit) ? dataModelOptions.limit : 100;
              this.treeGridActive = true;
              var value = 'THIS IS A ColChartDataModel...';
              //$scope.value = value;
              this.updateScope(value);  // see WidgetDataModel factory           
          },

          updateLimit: function (limit) {
              this.dataModelOptions = this.dataModelOptions ? this.dataModelOptions : {};
              this.dataModelOptions.limit = limit;
              this.limit = limit;
          },

          destroy: function () {
              WidgetDataModel.prototype.destroy.call(this);
          }
      });

      return ColumnChartDataModel;
  });

and finally the directives:

'use strict';

angular.module('rage')
  .directive('wtTime', function ($interval) {
    return {
      restrict: 'A',
      scope: true,
      replace: true,
      template: '<div>Time<div class="alert alert-success">{{time}}</div></div>',
      link: function (scope) {
        function update() {
          scope.time = new Date().toLocaleTimeString();
        }

        update();

        var promise = $interval(update, 500);

        scope.$on('$destroy', function () {
          $interval.cancel(promise);
        });
      }
    };
  })
  .directive('wtScopeWatch', function () {
    return {
      restrict: 'A',
      replace: true,
      template: '<div>Value<div class="alert alert-info">{{value}}</div></div>',
      scope: {
        value: '=value'
      }
    };
  })
  .directive('wtFluid', function () {
    return {
      restrict: 'A',
      replace: true,
      templateUrl: 'app/views/template2/fluid.html',
      scope: true,
      controller: function ($scope) {
        $scope.$on('widgetResized', function (event, size) {
          $scope.width = size.width || $scope.width;
          $scope.height = size.height || $scope.height;
        });
      }
    };
  });

I'd like to know why ONLY the directive option will update the wigdet's data and not the template option.

thank you, Bob

Upvotes: 0

Views: 1274

Answers (1)

AndyPerlitch
AndyPerlitch

Reputation: 4729

I believe I see the problem. The dataAttrName setting and updateScope method are actually doing something other than what you're expecting.

Look at the makeTemplateString function here. This is what ultimately builds your widget's template. You should notice that if you supply a template, the dataAttrName does not even get used.

Next, take a look at what updateScope does, and keep in mind that you can override this function in your own data model to do what you really want, a la:

angular.extend(TreeGridDataModel.prototype, {

  init: function() {...},
  destroy: function() {...},
  updateScope: function(data) {
    // I don't see this "main" object defined anywhere, I'm just going 
    // off your treegrid.html template, which has jqx-settings="main.treeGridOptions"
    this.widgetScope.main = { treeGridOptions: data };

     // Doing it without main, you could just do:
     // this.widgetScope.treeGridOptions = data;

     // And then update your treegrid.html file to be:
     // <div id="treeGrid" jqx-tree-grid jqx-settings="treeGridOptions"></div>
  }
});

Upvotes: 2

Related Questions