Passing data to a transmitted item

I want to create a directive that organizes the display of data grouped by date. I also want to specify a directive that will display individual lines. In an ideal world, it would look something like this (but beautiful and beautiful)

Friday, Oct 28 [some directive html] [some directive html] [some directive html] Saturday, Oct 29 [some directive html] Sunday, Oct 30 [some directive html] [some directive html] ... 

This obviously does not work, so if you have a better approach, tell me, but I was hoping to do something in this direction:

 app.directive('dateOrganized', [function(){ return { template: '<div>' + '<div ng-repeat="organizedDate in organizedDate">' + '<div>{{organizedDate.date | date}}</div>' + '<div ng-repeat="item in organizedDate.items">' + '{{rowDirectiveHtml}}' + '</div>' + '</div>' + '</div>', scope: { organizedDates: '=', rowDirectiveHtml: '=' } ... }; }]) app.directive('itemRow', [function(){ return { template: '<div>{{item.data}}</div>', scope: { item: '=' } }; }]); 

then use it as follows:

 <div data-organized organized-dates="stuff" row-directive-html="<div item-row item=\"item\" />" /> 

I know this is very ugly (and not working, but I'm sure I can get it to work with multiple settings), so I really ask if there is a better way to do this?

+6
source share
1 answer

This question is more complex than it might seem, so let it break.

What you are building is a directive that accepts a partial template - <div item-row item="item" /> - and that uses (or associates with region c) with an internal variable - item is not user-defined in the external volume; its value is determined by your directive, and your user "discovers" it by reading the documentation of your directive. I usually call these "magic" variables the $ prefix, for example. $item .

Step 1

Instead of passing the template as HTML-as-string via attribute binding, pass it as content and translate that content. Transcluding allows you to associate broadcast content with an arbitrary scope:

 <foo> <div>my item is: {{$item}}</div> </foo> 
 .directive("foo", function(){ return { scope: {}, transclude: true, template: "<h1>I am foo</h1><placeholder></placeholder>", link: function(scope, element, attrs, ctrls, transclude){ scope.$item = "magic variable"; transclude(scope, function(clonedContent){ element.find("placeholder").replaceWith(clonedContent); }); } }; }); 

The above will post the template <div>my item is: {{$item}}</div> (there can be any template you specify) where the foo directive solves and will refer to the area that has $item .

Step 2

But the added complexity of your directive is that it uses ng-repeat , which itself accepts the template, and the template that your directive receives should be used as the ng-repeat template.

Using only the above approach, this will not work, since by the time the link is executed ng-repeat will already broadcast its own content before you have the opportunity to apply yours.

One way to access this is to manually $compile the foo template instead of using the template property. Before compilation, we will have the opportunity to place the required template where necessary:

 .directive("foo", function($compile){ return { scope: {}, transclude: true, link: function(scope, element, attrs, ctrls, transclude){ scope.items = [1, 2, 3, 4]; var template = '<h1>I am foo</h1>\ <div ng-repeat="$item in items">\ <placeholder></placeholder>\ </div>'; var templateEl = angular.element(template); transclude(scope, function(clonedContent){ templateEl.find("placeholder").replaceWith(clonedContent); $compile(templateEl)(scope, function(clonedTemplate){ element.append(clonedTemplate); }); }); } }; }); 

Demo

+11
source

All Articles