数据传递给transcluded元 [英] Pass data to transcluded element
问题描述
我要创建一个组织按日期分组的数据显示一个指令。我也希望能够指定一个指令,将显示各行。在一个完美的世界,将是这个样子的(但好和pretty)
I want to create a directive that organizes a displays data grouped by date. I also want to be able to specify a directive that will display the individual rows. In a perfect world it would look something like this (but nice and pretty)
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 doesn't work, so if you have a better approach please tell me, but I was hoping to be able to do something along these lines:
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 like this:
<div data-organized organized-dates="stuff" row-directive-html="<div item-row item=\"item\" />" />
我知道这是超级难看的(并且不工作,但我敢肯定,我可以把它与一些调整的工作),所以我真的很问,有没有更好的方法来做到这一点?
I know this is super ugly (and doesn't work, but I'm sure I could get it working with a few tweaks) so what I am really asking, is there a better way to do this?
推荐答案
这问题比可能会出现,所以让我们把它分解更加复杂。
This question is more complicated than might appear, so let's break it down.
你所构建的是,接受局部模板指令 - &LT; DIV项目行项目=项/&GT;
- 和的该模板使用(或反对使用范围链接)的内部变量 - 项目
- 未在外部范围由用户定义;通过阅读你的指令的文件其含义是由您的指令和您的用户定义的发现它。我通常名称以prefixed $
,例如这种神奇的变量 $项目
。
What you are building is a directive that accepts a partial template - <div item-row item="item" />
- and that template uses (or linked against a scope with) an inner variable - item
- that is not defined in the outer scope by the user; its meaning is defined by your directive and your user "discovers" it by reading the documentation of your directive. I typically name such "magic" variables with a prefixed $
, e.g. $item
.
第1步
而不是传递一个模板,通过绑定属性的HTML作为字符串的,把它作为内容和transclude内容。 Transcluding允许你对任意范围transcluded内容绑定:
Instead of passing a template as an HTML-as-string via attribute binding, pass it as contents and transclude that content. Transcluding allows you to bind the transcluded content against 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);
});
}
};
});
以上将会把模板&LT; DIV&gt;我的项目是:{{$项目}}&LT; / DIV&GT;
(可能是你指定的任何模板),其中该指令富
决定,并且都会连接有 $项目
定义。
The above will place the template <div>my item is: {{$item}}</div>
(could be any template you specify) where the directive foo
decides, and will link against a scope that has $item
defined.
第2步
但你的指令增加了复杂性在于它使用 NG-重复
,这本身接受一个模板,你的指令接收需要的模板被用作模板 NG-重复
。
But the added complexity of your directive is that it uses ng-repeat
, which by itself accepts a template, and the template your directive receives needs to be used as a template of ng-repeat
.
通过正上方的办法,这将不是由时间工作,因为链接
运行, NG-重复
你有机会申请之前,你会已经transcluded自己的内容。
With just the approach above, this would not work, since by the time link
runs, ng-repeat
will have already transcluded its own content before you had a chance to apply yours.
要解决的一个方法是手动 $编译
富
的模板,而不是使用模板
属性。在编译之前,我们将有机会来放置预期的模板在需要的地方:
One way to address that is to manually $compile
the template of foo
instead of using the template
property. Prior to compiling, we will have a chance to place the intended template where needed:
.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
这篇关于数据传递给transcluded元的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!