问题
I've a directive as follows:
<selectable-item-list items="model.items">
<item-template>
<span ng-bind="item.text"></span>
</item-template>
</selectable-item-list>
The issue is in the <item-template>
, where item
would be a reference of currently iterated item when an internal ng-repeat
is bound inside <selectable-item-list>
.
AFAIK, it seems like transclusions can't see directive's scope, thus, that item.text
can't be bound because there's no item
at all.
How would you solve this scenario? Previously I was manually-transcluding <item-template>
but that other approach had other downsides/issues.
Here's a runnable code snippet that works as sample of my real-world case:
var app = angular.module("app", []);
app.controller("some", function() {
this.items = [{
text: "hello"
}, {
text: "bye"
}];
});
app.directive("test", function() {
return {
template: `<ol>
<li ng-repeat="item in items">
<div ng-transclude="itemTemplate"></div>
</li>
</ol>`,
transclude: {
"itemTemplate": "itemTemplate"
},
scope: {
"items": "="
}
}
});
<script src="https://code.angularjs.org/1.5.7/angular.js"></script>
<div ng-app="app" ng-controller="some as some">
<test items="some.items">
<item-template>
<span ng-bind="item.text"></span>
</item-template>
</test>
</div>
回答1:
I had a wrong assumption! When I said that a transcluded content couldn't access the containing directive scope I was wrong because of this other Q&A: Why ng-transclude's scope is not a child of its directive's scope - if the directive has an isolated scope? which is absolutely outdated.
In fact, there's another answer as part of the same Q&A where someone has described that now this has been fixed and a transcluded content can access its direct directive scope using $parent.
So I fixed my issue just replacing the item
property access with $parent.item
and it worked!
I've added a working code snippet which has this fix:
var app = angular.module("app", []);
app.controller("some", function() {
this.items = [{
text: "hello"
}, {
text: "bye"
}];
});
app.directive("test", function() {
return {
template: `<ol>
<li ng-repeat="item in items">
<div ng-transclude="itemTemplate"></div>
</li>
</ol>`,
transclude: {
"itemTemplate": "itemTemplate"
},
scope: {
"items": "="
}
}
});
<script src="https://code.angularjs.org/1.5.7/angular.js"></script>
<div ng-app="app" ng-controller="some as some">
<test items="some.items">
<item-template>
<span ng-bind="$parent.item.text"></span>
</item-template>
</test>
</div>
来源:https://stackoverflow.com/questions/38267288/force-scope-to-named-slot-with-ng-transclude