[英]Angularjs: transclude directive template
在以下情況下如何使用嵌入。 目的是在 html(部分)文件中使用標記,而不是在模板中(在指令內)定義它。
我在這里找到了一個很棒的樹指令。 ( 來源)原文: http : //jsfiddle.net/n8dPm/
我沒有在指令中定義模板,而是嘗試使用嵌入的內容。 我還將 Angular 更新為 1.2.0.rc2。 更新: http : //jsfiddle.net/aZx7B/2/
得到以下錯誤
類型錯誤:對象 [object Object] 的屬性“$transclude”不是函數
代碼:
module.directive("tree", function($compile) {
return {
restrict: "E",
transclude: true,
scope: {family: '='},
template:
'<ul>' +
'<li ng-transclude></li>' +
'<li ng-repeat="child in family.children">' +
'<tree family="child"></tree>' +
'</li>' +
'</ul>',
compile: function(tElement, tAttr) {
var contents = tElement.contents().remove();
var compiledContents;
return function(scope, iElement, iAttr) {
if(!compiledContents) {
compiledContents = $compile(contents);
}
compiledContents(scope, function(clone, scope) {
iElement.append(clone);
});
};
}
};
});
<div ng-app="myapp">
<div ng-controller="TreeCtrl">
<tree family="family">
<p>{{ family.name }}</p>
</tree>
</div>
</div>
在大衛的建議下,做了一些改動。 http://jsfiddle.net/aZx7B/3/現在,它打印,父。 改變, family
-> treeFamily
雖然不起作用
您還需要在模板中輸出家庭的名稱: http : //jsfiddle.net/roadprophet/DsvX6/
module.directive("tree", function($compile) {
return {
restrict: "E",
transclude: true,
scope: {family: '='},
template:
'<ul>' +
'<li ng-transclude></li>' +
'<li ng-repeat="child in family.children">' +
'<tree family="child">{{family.name}}</tree>' +
'</li>' +
'</ul>',
compile: function(tElement, tAttr, transclude) {
var contents = tElement.contents().remove();
var compiledContents;
return function(scope, iElement, iAttr) {
if(!compiledContents) {
compiledContents = $compile(contents, transclude);
}
compiledContents(scope, function(clone, scope) {
iElement.append(clone);
});
};
}
};
});
編輯
你也可以通過這樣做來簡化: http : //jsfiddle.net/roadprophet/DsvX6/2/
<div ng-app="myapp">
<div ng-controller="TreeCtrl">
<tree family="treeFamily">
</tree>
</div>
</div>
module.directive("tree", function($compile) {
return {
restrict: "E",
transclude: true,
scope: {family: '='},
template:
'<ul>' +
'<li ng-transclude></li>' +
'<p>{{ family.name }}</p>' +
'<li ng-repeat="child in family.children">' +
'<tree family="child"></tree>' +
'</li>' +
'</ul>',
compile: function(tElement, tAttr, transclude) {
var contents = tElement.contents().remove();
var compiledContents;
return function(scope, iElement, iAttr) {
if(!compiledContents) {
compiledContents = $compile(contents, transclude);
}
compiledContents(scope, function(clone, scope) {
iElement.append(clone);
});
};
}
};
});
編輯雖然問題的來源相同。 沒有模板被傳遞給內部樹指令。 http://jsfiddle.net/roadprophet/DsvX6/3/
<div ng-app="myapp">
<div ng-controller="TreeCtrl">
<tree family="treeFamily">
<p>{{ family.name }}</p>
</tree>
</div>
</div>
template:
'<ul>' +
'<li ng-transclude></li>' +
'<li ng-repeat="child in family.children">' +
'<tree family="child"><div ng-transclude></div></tree>' +
'</li>' +
'</ul>'
您想針對父作用域編譯嵌入的 DOM; 您可以使用指令的控制器定義中的可注入$transclude
函數自動執行此操作:
module.directive("tree", function($compile) {
return {
restrict: "E",
transclude: true,
scope: { family: '=' },
template: '<ul>' +
'<li ng-repeat="child in family.children">' +
'<tree family="child">' +
'<p>{{ child.name }}</p>' +
'</tree>' +
'</li>' +
'</ul>',
controller: function($element, $transclude) {
$transclude(function(e) {
$element.append(e);
});
},
compile: function(tElement, tAttr, transclude) {
var contents = tElement.contents().remove();
var compiledContents;
return function(scope, iElement, iAttr) {
if(!compiledContents) {
compiledContents = $compile(contents);
}
compiledContents(scope, function(clone) {
iElement.append(clone);
});
};
}
};
});
這允許您在根模板中使用父作用域屬性treeFamily
(還要注意上面指令模板中child
的使用):
<div ng-app="myapp">
<div ng-controller="TreeCtrl">
<tree family="treeFamily">
<p>{{ treeFamily.name }}</p>
</tree>
</div>
</div>
你可以在這里看到一個例子: http : //jsfiddle.net/BinaryMuse/UzHeW/
晚會很晚了。 我在一個項目中需要這個,所以在深入研究並找到其他很好的方法和方向之后,終於想出了這個:
與ng-transclude
指令相同的代碼,但添加了少量context
綁定,該指令在每次更改時監視和設置嵌入生成的范圍。 與ng-repeat
相同,但這允許:
增強的 ng-transclude 函數:
return function ngTranscludePostLink(
...
) {
let context = null;
let childScope = null;
...
$scope.$watch($attrs.context, (newVal, oldVal) => {
context = newVal;
updateScope(childScope, context);
});
...
$transclude(ngTranscludeCloneAttachFn, null, slotName);
...
function ngTranscludeCloneAttachFn(clone, transcludedScope) {
...
$element.append(clone);
childScope = transcludedScope;
updateScope(childScope, context);
...
}
...
function updateScope(scope, varsHash) {
if (!scope || !varsHash) {
return;
}
angular.extend(scope, varsHash);
}
}
它的用法是:
應用程序
<my-list items="$ctrl.movies">
<div>App data: {{ $ctrl.header }}</div>
<div>Name:{{ name }} Year: {{ year }} Rating: {{ rating
}}</div>
</my-list>
我的列表
<ul>
<li ng-repeat="item in $ctrl.items track by item.id">
<div>Ng repeat item scope id: {{ $id }}</div>
<cr-transclude context="item"></cr-transclude>
</li>
</ul>
完整的指令代碼可以在 GitHub 上找到
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.