0

I'm building a dashboard component to allow users to add widgets that expose various metrics of the underlying database. Each widget is a distinct directive. In order to properly size the widget in the dashboard, I need to access a property defined in the directive's template but struggling to find a way to do so.

I'm adding the widget by compiling its directive:

divWidget = $compile("<" + widgetName + " test='3'></" + widgetName + ">")($scope);

This then gets .appended to the dashboard container:

divContainer = $("<div class='cell' style='width:" + w + "px;height:" + h + "px'></div>");
divContainer.append(divWidget);
$(element).append(divContainer);

I need to set the values of "w" and "h", and I'm embedding these attributes inside the widget's directive template:

<div class="widget" my-rows="1" my-cols="3">

The question is, how do I access my-rows and my-cols once the directive has been compiled? I know I could define a service per widget to access the widget's configuration externally, but this seems like massive overhead.

In the example above, I can access the "test" attribute easily enough, but not the "my-rows" or "my-cols".

2 Answers2

0

You could set replace: true in the directive definition, and then all the attributes + classes on the root element of the directive template get merged together with the ones on the original element in the parent template. So if you have

<my-widget test="3"></my-widget>

with a myWidget definition that includes

replace: true,
template: '<div class="widget" my-rows="1" my-cols="3">Contents of widget</div>',

then the compiled DOM would look like

<div class="widget" my-rows="1" my-cols="3" test="3">Contents of widget</div>

and you can access the attributes added by the directive in the same way as the ones in the parent template. You can see an example of this at http://plnkr.co/edit/wIXlYIaNfdd0KNZG7vke

However as can be seen in the docs for $compile, replace: true is deprecated, and will be removed in v2.0. However, I suspect that so many things won't be backwards compatible, that this may be the least of your concerns if/when you want to migrate to v2.0

Michal Charemza
  • 25,940
  • 14
  • 98
  • 165
0

The directive could access its template directly, and then set the attributes on the parent element:

app.directive('myWidget', function() {
  return {
    restrict: 'E',
    template: '<div class="widget" my-rows="1" my-cols="3">Contents of widget</div>',
    link: function(scope, element, attrs) {
      var myRows = element.children().attr('my-rows');
      attrs.$set('myRows', myRows);
      var myCols = element.children().attr('my-cols');
      attrs.$set('myCols', myCols);
    }
  };
});

which can be seen at http://plnkr.co/edit/1qiHvc1Teq2BeiO1ZSsm?p=preview

Michal Charemza
  • 25,940
  • 14
  • 98
  • 165