Javascript 如何通过ngRepeat“;模板";使用transclude将指令转换为NGO指令?
演示: 我有一个名为myDirective的ng指令,在指令模板中,我有一个使用ng repeat打印的li标签列表。我想将li标记的内容声明为myDirective声明的一部分,并使用transclude打印所需的text/html内容。通过这种方式,我可以很好地分离关注点,这样我的指令就不需要知道源项的结构,并且调用方负责布局li的内容 如下所示:Javascript 如何通过ngRepeat“;模板";使用transclude将指令转换为NGO指令?,javascript,angularjs,angularjs-directive,angularjs-ng-repeat,Javascript,Angularjs,Angularjs Directive,Angularjs Ng Repeat,演示: 我有一个名为myDirective的ng指令,在指令模板中,我有一个使用ng repeat打印的li标签列表。我想将li标记的内容声明为myDirective声明的一部分,并使用transclude打印所需的text/html内容。通过这种方式,我可以很好地分离关注点,这样我的指令就不需要知道源项的结构,并且调用方负责布局li的内容 如下所示: <my-directive source="vm.source">{{label}} and {{id}}</my-direc
<my-directive source="vm.source">{{label}} and {{id}}</my-directive>
{label}和{{id}
甚至
<my-directive source="vm.source"><a href="#{{id}}">{{label}}</a></my-directive>
ngRepeat(在myDirective内部)的模板如下所示
template: '<ul><li ng-repeat="item in source" ng-transclude></li></ul>',
模板:'
,
但我无法让转换在hg repeat内部工作。我使用的是angular 1.2.19的最新版本。确切地说,trasnclusion有效,但我在指令级传递的表达式无效
请帮忙,谢谢你
我想不出更好的题目了。欢迎你把它做得更好
更新:我选择了@pixelbits的答案,因为这正是我想要的。但我实际上使用了@Norguard的方法,因为它更具角度。杰夫,你的转置有点落后 或者,更重要的是,与你认为他们的工作方式相比,他们的工作方式有点落后 如果您有一个transcluding指令,并且将内容放入其中,则内容是从transclude指令的父级读取的,而不是从指令本身读取的 例如,假设:
<div ng-controller="parentController as parent">
<transcluding-directive>
{{ key }} {{ val }}
</transcluding-directive>
</div>
然后,内容将被拉起,并附加到由transcludingDirective.querySelector(“[ng transclude]”)找到的节点上。
这实际上并不是它的确切工作原理,但它是您得到的结果(在指令中,您不需要执行自己的编译/转置例程)
当您知道第一个错误时,第二个错误会更加明显:vm
的{label}}和{id}}是vm
的$scope
对象上的属性
它们不存在于$scope
上,因此未定义
,这就是从模板中获取'+'和'+'
的原因。
您正在为传递给指令的每个项创建一个
,但您正在为每个项插入未定义的和未定义的
您编写的指令应该是一个专门的指令(知道如何构建确切类型的列表的指令)
或者是一个通用指令,您可以将列表输入其中
<generic-drawer>
<ul><li ng-repeat="item in vm.list">{{item.label}} {{item.id}}</li></ul>
</generic-drawer>
- {{item.label}{{{item.id}}
…它甚至可能是一个特定的指令,知道如何在其模板内提供更通用的指令
<specific-list items="vm.list"></specific-list>
<!-- specific-list.html -->
<generic-drawer>
<generic-toggle ng-repeat="item in items">{{ item.label }} {{ item.id }}</generic-toggle>
</generic-drawer>
{{item.label}{{item.id}
这是Angular(和聚合物,以及将来的Web组件本身)很适合的成分
作为我一直从事的一个项目的一个简单示例,我有一些元素可以过滤,如下所示:
<transcluding-directive></transcluding-directive>
<div>{{ transcludedContent }}</div>
<page-type-a></page-type-a>
<!-- page-type-a.html -->
<card-collection cards="page.items"></card-collection>
<!-- card-collection.html -->
<header ><!-- ... header stuff --></header>
<card ng-repeat="card in cards"></card>
<!-- card.html -->
<header><h1>{{ title }}</h1></header>
<blockquote>{{ content }}</blockquote>
<cite>{{ author }}</cite>
<page-type-b></page-type-b>
<!-- page-type-b.html -->
<card-collection cards="page.items"></card-collection>
{{title}}
{{content}}
{{作者}
每个组件只做自己的工作
还有其他方法可以让它工作(输入一个“key”属性和一个“value”属性,并在将$scope
实例链接到transcluding指令的内部模板之前,从列表中的每个项目中提取值以组成自己的内部列表,用于ng repeat
…或从转置内容中准备值…)…但在这种情况下,这样做听起来很疯狂。转包内容是针对父范围的子范围(也称为转包范围,但这与指令的隔离范围不同)编译的。也就是说,您可以在父HTML中指定模板(尽管在angular中它有点超出正常用例),并根据指令的独立范围手动编译它
HTML
<body ng-app="myApp">
<div ng-controller="myController as vm">
<my-directive source="vm.source">
<span>{{item.label}} and {{item.id}}</span>
</my-directive>
</div>
</body>
{{item.label}和{{item.id}
请注意,我的指令的内部HTML引用了必须在指令范围内定义的“item”
指令
function directive($compile) {
return {
restrict: 'E',
scope: {
source: '='
},
compile: function(element, attr) {
// in the compile phase, remove the contents
// of element so that it is not compiled by angular.
// We will be manually compiling it in the link function.
var template = angular.element('<ul><li ng-repeat="item in source">' + element.html() + '</li></ul>');
element.empty();
// link function
return function(scope, element, attr) {
// append the template
element.append(template);
// compile and link the template against the isolated scope.
$compile(template)(scope);
}
}
};
}
函数指令($compile){
返回{
限制:'E',
范围:{
来源:'='
},
编译:函数(元素,属性){
//在编译阶段,删除内容
//元素,使其不被角度编译。
//我们将在link函数中手动编译它。
var template=angular.element('- '+element.html()+'
');
元素。empty();
//链接功能
返回函数(范围、元素、属性){
//附加模板
元素。追加(模板);
//编译模板并将其链接到隔离范围。
$compile(模板)(范围);
}
}
};
}
Hmmm。。。我想我需要多读一点关于角度的知识。事实上,我有我想要的工作,但方式不同。我将格式化程序函数从控制器传递到指令,该指令为每个li输出所需的格式。但我认为这将是一种更具陈述性的(有角度的)方式来解决我的问题。谢谢你的回答,我会再深入一点,这绝对是可能的。你几乎可以钩住棱角的任何部分,并根据自己的意愿弯曲它。但是,当您编写指令来包装其他指令时,代码会变得简单得多,而不是编写大型预编译或后转置、预链接代码
function directive($compile) {
return {
restrict: 'E',
scope: {
source: '='
},
compile: function(element, attr) {
// in the compile phase, remove the contents
// of element so that it is not compiled by angular.
// We will be manually compiling it in the link function.
var template = angular.element('<ul><li ng-repeat="item in source">' + element.html() + '</li></ul>');
element.empty();
// link function
return function(scope, element, attr) {
// append the template
element.append(template);
// compile and link the template against the isolated scope.
$compile(template)(scope);
}
}
};
}