ng-repeat 在指令中不起作用
ng-repeat not working within directive
我为 drop.js 创建了一个 Angular 包装器,它是一个 javascript 弹出窗口库。
除了使用 ng-repeat 外,在 drop 指令中一切正常,包括正常的 Angular 绑定。
这是一个屏幕截图,请注意弹出窗口的内容有一个绑定到控制器的值,但 ng-repeat 没有显示任何数据。
这是完整的 plunker:http://plnkr.co/edit/plcUAWCRQ009blhY3nqF?p=preview
这是一个用法示例:
<button>
button text {{someValue}}
<ul>
<li ng-repeat="thing in things">button text {{thing.code}} - {{thing.name}}</li>
</ul>
<drop classes='classes' position='position'>
<div>
Hello {{ $parent.someValue}}
<br>
<ul>
<!-- here is the problem, ng-repeat does not compile correctly -->
<li ng-repeat="thing in $parent.things">{{thing.code}} - {{thing.name}}</li>
</ul>
</div>
</drop>
</button>
指令代码如下:
.directive('drop', function ($compile) {
return {
restrict: 'E',
replace: true,
transclude: true,
scope: {
classes: '=?',
constrainToScrollParent: '=?',
constrainToWindow: '=?',
position: '=?',
openOn: '=?'
},
template: '<div><div ng-transclude></div></div>',
link: function (scope, element, attrs) {
var drop;
var target = element[0].parentElement;
var compiled = $compile(element[0].children[0].innerHTML);
var initDrop = function() {
if (drop) {
drop.destroy();
}
// some default values go here if they weren't passed in....
drop = new Drop({
target: target,
content: compiled(scope)[0],
classes: scope.classes,
constrainToScrollParent: scope.constrainToScrollParent,
constrainToWindow: scope.constrainToWindow,
position: scope.position,
openOn: scope.openOn
});
}
initDrop();
// clean up element
element[0].innerHTML = '';
// some watchers go here....
}
}
});
你可以试试 transcludeFn
。我不确定您是否需要 pre
和 post
函数,或者是否可以将 transclude
函数直接放在 link
(postLink)中。 Plunker
.directive('drop', function ($compile) {
return {
restrict: 'E',
replace: true,
transclude: true,
scope: {
classes: '=?',
constrainToScrollParent: '=?',
constrainToWindow: '=?',
position: '=?',
openOn: '=?'
},
link: {
pre: function(scope, element, attrs, ctrl, transclude){
transclude(scope, function(clone, scope) {
element.append(clone);
});
},
post:function (scope, element, attrs) {
var drop;
var target = element[0].parentElement;
var compiled = $compile(element[0].children[0]);
var initDrop = function() {
if (drop) {
drop.destroy();
}
if (typeof scope.classes == 'undefined') scope.classes = 'drop-theme-arrows-bounce';
if (typeof scope.constrainToScrollParent == 'undefined') scope.constrainToScrollParent = true;
if (typeof scope.constrainToWindow == 'undefined') scope.constrainToWindow = true;
if (typeof scope.position == 'undefined') scope.position = 'top center';
if (typeof scope.openOn == 'undefined') scope.openOn = 'click';
drop = new Drop({
target: target,
content: compiled(scope)[0],
classes: scope.classes,
constrainToScrollParent: scope.constrainToScrollParent,
constrainToWindow: scope.constrainToWindow,
position: scope.position,
openOn: scope.openOn
});
}
initDrop();
// clean up element
element[0].innerHTML = '';
...
}
}
}
});
我为 drop.js 创建了一个 Angular 包装器,它是一个 javascript 弹出窗口库。
除了使用 ng-repeat 外,在 drop 指令中一切正常,包括正常的 Angular 绑定。
这是一个屏幕截图,请注意弹出窗口的内容有一个绑定到控制器的值,但 ng-repeat 没有显示任何数据。
这是完整的 plunker:http://plnkr.co/edit/plcUAWCRQ009blhY3nqF?p=preview
这是一个用法示例:
<button>
button text {{someValue}}
<ul>
<li ng-repeat="thing in things">button text {{thing.code}} - {{thing.name}}</li>
</ul>
<drop classes='classes' position='position'>
<div>
Hello {{ $parent.someValue}}
<br>
<ul>
<!-- here is the problem, ng-repeat does not compile correctly -->
<li ng-repeat="thing in $parent.things">{{thing.code}} - {{thing.name}}</li>
</ul>
</div>
</drop>
</button>
指令代码如下:
.directive('drop', function ($compile) {
return {
restrict: 'E',
replace: true,
transclude: true,
scope: {
classes: '=?',
constrainToScrollParent: '=?',
constrainToWindow: '=?',
position: '=?',
openOn: '=?'
},
template: '<div><div ng-transclude></div></div>',
link: function (scope, element, attrs) {
var drop;
var target = element[0].parentElement;
var compiled = $compile(element[0].children[0].innerHTML);
var initDrop = function() {
if (drop) {
drop.destroy();
}
// some default values go here if they weren't passed in....
drop = new Drop({
target: target,
content: compiled(scope)[0],
classes: scope.classes,
constrainToScrollParent: scope.constrainToScrollParent,
constrainToWindow: scope.constrainToWindow,
position: scope.position,
openOn: scope.openOn
});
}
initDrop();
// clean up element
element[0].innerHTML = '';
// some watchers go here....
}
}
});
你可以试试 transcludeFn
。我不确定您是否需要 pre
和 post
函数,或者是否可以将 transclude
函数直接放在 link
(postLink)中。 Plunker
.directive('drop', function ($compile) {
return {
restrict: 'E',
replace: true,
transclude: true,
scope: {
classes: '=?',
constrainToScrollParent: '=?',
constrainToWindow: '=?',
position: '=?',
openOn: '=?'
},
link: {
pre: function(scope, element, attrs, ctrl, transclude){
transclude(scope, function(clone, scope) {
element.append(clone);
});
},
post:function (scope, element, attrs) {
var drop;
var target = element[0].parentElement;
var compiled = $compile(element[0].children[0]);
var initDrop = function() {
if (drop) {
drop.destroy();
}
if (typeof scope.classes == 'undefined') scope.classes = 'drop-theme-arrows-bounce';
if (typeof scope.constrainToScrollParent == 'undefined') scope.constrainToScrollParent = true;
if (typeof scope.constrainToWindow == 'undefined') scope.constrainToWindow = true;
if (typeof scope.position == 'undefined') scope.position = 'top center';
if (typeof scope.openOn == 'undefined') scope.openOn = 'click';
drop = new Drop({
target: target,
content: compiled(scope)[0],
classes: scope.classes,
constrainToScrollParent: scope.constrainToScrollParent,
constrainToWindow: scope.constrainToWindow,
position: scope.position,
openOn: scope.openOn
});
}
initDrop();
// clean up element
element[0].innerHTML = '';
...
}
}
}
});