何时使用 Angular 包含
When to use Angular transclusion
我正在阅读 angular 包含本页中的一些示例:http://www.c-sharpcorner.com/UploadFile/17e8f6/transclusion-in-custom-angularjs-directive/
此页面提供了有用的示例。但是我想知道什么时候使用嵌入。原例:
<user-post user-name="{{user.Name}}" post-details="post" ng-repeat="post in user.Posts">
<user-likes post-likes-count="{{post.Likes.length}}"></user-likes>
</user-post>
这是 HTML userPost 指令的模板:
<div class="panel panel-default panel-primary">
<div class="panel-heading">
<h5><strong>{{userName}}</strong></h5>
</div>
<div class="panel-body">
<img ng-src="{{postDetails.Content}}" alt="Image" class="img-responsive" />
</div>
<div class="panel-footer" ng-transclude>
</div>
</div>
但我可以在不包含的情况下重写它:
<div class="panel panel-default panel-primary">
<div class="panel-heading">
<h5><strong>{{userName}}</strong></h5>
</div>
<div class="panel-body">
<img ng-src="{{postDetails.Content}}" alt="Image" class="img-responsive" />
</div>
<div class="panel-footer">
<user-likes post-likes-count="{{likeCount}}"></user-likes>
</div>
</div>
我想知道使用嵌入的最佳案例?
您将使用 transclude
将一堆 html 注入到您的指令中。创建指令的想法是让您拥有可在应用程序的各个部分中使用的可重用代码。 Transclusion 允许您从模板进一步自定义指令的内容。
按照您的示例,创建带有嵌入的 user-post
指令的想法是您的用户 post 可能不会在您的应用程序的不同部分拥有完全相同的内容。
如果您在 template 2
中注意到,我可以添加一些额外的 HTML 以适应指令中的不同内容。
模板 1:
<user-post user-name="{{user.Name}}" post-details="post" ng-repeat="post in user.Posts">
<user-likes post-likes-count="{{post.Likes.length}}"></user-likes>
</user-post>
模板 2:
<user-post user-name="{{otherUser.Name}}" post-details="post" ng-repeat="post in otherUser.Posts">
<user-likes post-likes-count="{{post.Likes.length}}"></user-likes>
// this directive might loop through post.comments and display a list
// of comments on the post.
<user-comments post-comments="{{post.comments}}"></user-comments>
<p>some other customize html</p>
</user-post>
现在我的应用程序中有 2 个用户 post。一个有 post 和用户喜欢,另一个有 post 有用户喜欢和评论。
要理解并 when/how 使用它,您必须稍微了解一下您试图表示的 DOM,以及 angular 指令如何在其中发挥作用DOM.
具体来说,这与作为元素 (restrict: 'E'
) 的指令有关。让我们使用最基本的 HTML 作为我们可能采用的指令:
.directive('myDirective', function(){
return {
restrict: 'E',
template: '<div></div>' +
'<div></div>'
};
用法:
<my-directive>Some Content</my-directive>
现在,这是理解嵌入的关键问题:
Some Content
的终点在哪里?
这样的话,Some Content
就无路可走了。当指令被注入 DOM 时,它被 template
取代。模板不知道Some Content
,没地方放,所以最后不会输出DOM.
现在,添加嵌入,我们可以解决这个问题。
.directive('myDirective', function(){
return {
restrict: 'E',
transclude: true,
template: '<div></div>' +
'<ng-transclude></ng-transclude>'
};
现在,编译 DOM 时,Some Content
有地方可以去。包含允许将元素的内部内容放置在模板中,在 ng-transclude
指令存在的位置。
现在,嵌入可能会变得非常棘手,尤其是当您将一个指令嵌套在另一个指令的内部内容中时,但它可能非常强大。但是,如果您的指令在标记中的元素内没有内容,则不需要嵌入。有更多的方法可以利用嵌入,但在它们的核心,它们最终都会回到这个概念。
同一个API提供了两个独立的功能:常规嵌入和元素嵌入。
对于常规嵌入,基本用例是:您想要将一些内容从一个模板包含或替换到另一个模板。使用常规嵌入有两种方法可以做到这一点:ngTransclude 指令和嵌入函数。
以下内容来自 Eric Greene,我认为这是对带代码的常规嵌入的很好解释,Understanding Transclusion.
ngTransclude
HTML代码
<div foo>
Some Content Here
</div>
JavaScript代码
.directive("foo", function() {
// returns the Directive Definition Object
return {
transclude: true,
template: "<div>the template</div><div ng-transclude></div>"
};
})
使用 ngTransclude 指令的结果是以下 HTML 输出。
HTML代码
<div foo>
<div>the template</div>
<div ng-transclude>Some Content Here</div>
</div>
嵌入函数
The second method to do transclusion is to use the transclude function
provided in the post-link function of a directive. In the code below,
the link property points to the post-link function. Unless a pre-link
function is specifically provided, all references to a link function
refer to the post-link function. Review the code below to see how the
same goal is achieved with a transclude function:
HTML代码
<div foo>
Some Content Here
</div>
JavaScript Code
.directive("foo", function() {
return {
template: "<div>the template</div>",
transclude: true,
link: function(scope, element, attrs, ctrl, transclude) {
transclude(function(clone) {
element.append(clone);
});
}
};
})
The transclude function is passed an argument that is a callback
function used to manipulate the cloned element. In the code above, the
callback function will receive the cloned content as a parameter, then
the function adds the cloned content to the DOM. The execution of the
of link function results in the following HTML output:
HTML代码
<div foo>
<div>
the template
<div>Some Content Here</div>
</div>
</div>
但是,对于元素嵌入,我想扩展他的回答,因为他的解释对于用例来说似乎令人困惑且不完整。在 Tero Parviainen 的博客“A Guide to Transclusion in Angularjs”中,他找到了元素嵌入的根源,主要是为了延迟 UI 某些部分的链接和附件。
引用他的话:
了解元素嵌入
Let's now turn our attention to an alternative way you can use
transclusion: Doing element transclusion with transclude: 'element'.
One use case for element transclusion is when you want to defer the
linking and attachment for some part of your UI until something
happens. Since element transclusion essentially removes part of the
DOM and makes it available for you to put back using the transclusion
function, you have control into when that happens.
For example, you
might want to only link and attach part of the DOM after some
condition on the parent scope becomes true: What we have here is
essentially a simplified version of ngIf. If you look at the source
code of ngIf, you should now be able to understand what it's doing:
It's using element transclusion to conditionally link this part of the
DOM only when the condition expression is true. This also explains why
you see HTML comments in your DOM tree whenever ngIf is used. They're
inserted by element transclusion.
当我在页面上查看源代码时,我会在 Chrome 开发工具的“元素”选项卡中看到这一点,但不明白它的来源。我也用 ng-repeat 看到了它。
Repeated Rendering with Element Transclusion. Another use case for
element transclusion is if you want to link and attach part of the DOM
several times.
For example, you could have a directive that iterates
over an array and renders the DOM subtree again for each item in the
array, also making each item available on the scope. This can all be
done when we combine the element transclusion mechanism with the clone
attach function, because then we can link a new clone for the DOM for
each item: This is essentially a (hugely) simplified version of
ngRepeat. The built-in ngRepeatdirective also uses element
transclusion, though studying its source code is not quite as easy as
with ngIf because of the various ways you can use ngRepeatand all the
optimizations it contains. At the heart of it though, it's just an
application of element transclusion and the clone attach function.
我觉得 Tero 关于元素使用 Transclusion 的报道比我想象的要好。
我正在阅读 angular 包含本页中的一些示例:http://www.c-sharpcorner.com/UploadFile/17e8f6/transclusion-in-custom-angularjs-directive/
此页面提供了有用的示例。但是我想知道什么时候使用嵌入。原例:
<user-post user-name="{{user.Name}}" post-details="post" ng-repeat="post in user.Posts">
<user-likes post-likes-count="{{post.Likes.length}}"></user-likes>
</user-post>
这是 HTML userPost 指令的模板:
<div class="panel panel-default panel-primary">
<div class="panel-heading">
<h5><strong>{{userName}}</strong></h5>
</div>
<div class="panel-body">
<img ng-src="{{postDetails.Content}}" alt="Image" class="img-responsive" />
</div>
<div class="panel-footer" ng-transclude>
</div>
</div>
但我可以在不包含的情况下重写它:
<div class="panel panel-default panel-primary">
<div class="panel-heading">
<h5><strong>{{userName}}</strong></h5>
</div>
<div class="panel-body">
<img ng-src="{{postDetails.Content}}" alt="Image" class="img-responsive" />
</div>
<div class="panel-footer">
<user-likes post-likes-count="{{likeCount}}"></user-likes>
</div>
</div>
我想知道使用嵌入的最佳案例?
您将使用 transclude
将一堆 html 注入到您的指令中。创建指令的想法是让您拥有可在应用程序的各个部分中使用的可重用代码。 Transclusion 允许您从模板进一步自定义指令的内容。
按照您的示例,创建带有嵌入的 user-post
指令的想法是您的用户 post 可能不会在您的应用程序的不同部分拥有完全相同的内容。
如果您在 template 2
中注意到,我可以添加一些额外的 HTML 以适应指令中的不同内容。
模板 1:
<user-post user-name="{{user.Name}}" post-details="post" ng-repeat="post in user.Posts">
<user-likes post-likes-count="{{post.Likes.length}}"></user-likes>
</user-post>
模板 2:
<user-post user-name="{{otherUser.Name}}" post-details="post" ng-repeat="post in otherUser.Posts">
<user-likes post-likes-count="{{post.Likes.length}}"></user-likes>
// this directive might loop through post.comments and display a list
// of comments on the post.
<user-comments post-comments="{{post.comments}}"></user-comments>
<p>some other customize html</p>
</user-post>
现在我的应用程序中有 2 个用户 post。一个有 post 和用户喜欢,另一个有 post 有用户喜欢和评论。
要理解并 when/how 使用它,您必须稍微了解一下您试图表示的 DOM,以及 angular 指令如何在其中发挥作用DOM.
具体来说,这与作为元素 (restrict: 'E'
) 的指令有关。让我们使用最基本的 HTML 作为我们可能采用的指令:
.directive('myDirective', function(){
return {
restrict: 'E',
template: '<div></div>' +
'<div></div>'
};
用法:
<my-directive>Some Content</my-directive>
现在,这是理解嵌入的关键问题:
Some Content
的终点在哪里?
这样的话,Some Content
就无路可走了。当指令被注入 DOM 时,它被 template
取代。模板不知道Some Content
,没地方放,所以最后不会输出DOM.
现在,添加嵌入,我们可以解决这个问题。
.directive('myDirective', function(){
return {
restrict: 'E',
transclude: true,
template: '<div></div>' +
'<ng-transclude></ng-transclude>'
};
现在,编译 DOM 时,Some Content
有地方可以去。包含允许将元素的内部内容放置在模板中,在 ng-transclude
指令存在的位置。
现在,嵌入可能会变得非常棘手,尤其是当您将一个指令嵌套在另一个指令的内部内容中时,但它可能非常强大。但是,如果您的指令在标记中的元素内没有内容,则不需要嵌入。有更多的方法可以利用嵌入,但在它们的核心,它们最终都会回到这个概念。
同一个API提供了两个独立的功能:常规嵌入和元素嵌入。
对于常规嵌入,基本用例是:您想要将一些内容从一个模板包含或替换到另一个模板。使用常规嵌入有两种方法可以做到这一点:ngTransclude 指令和嵌入函数。
以下内容来自 Eric Greene,我认为这是对带代码的常规嵌入的很好解释,Understanding Transclusion.
ngTransclude
HTML代码
<div foo>
Some Content Here
</div>
JavaScript代码
.directive("foo", function() {
// returns the Directive Definition Object
return {
transclude: true,
template: "<div>the template</div><div ng-transclude></div>"
};
})
使用 ngTransclude 指令的结果是以下 HTML 输出。 HTML代码
<div foo>
<div>the template</div>
<div ng-transclude>Some Content Here</div>
</div>
嵌入函数
The second method to do transclusion is to use the transclude function provided in the post-link function of a directive. In the code below, the link property points to the post-link function. Unless a pre-link function is specifically provided, all references to a link function refer to the post-link function. Review the code below to see how the same goal is achieved with a transclude function:
HTML代码
<div foo>
Some Content Here
</div>
JavaScript Code
.directive("foo", function() {
return {
template: "<div>the template</div>",
transclude: true,
link: function(scope, element, attrs, ctrl, transclude) {
transclude(function(clone) {
element.append(clone);
});
}
};
})
The transclude function is passed an argument that is a callback function used to manipulate the cloned element. In the code above, the callback function will receive the cloned content as a parameter, then the function adds the cloned content to the DOM. The execution of the of link function results in the following HTML output:
HTML代码
<div foo>
<div>
the template
<div>Some Content Here</div>
</div>
</div>
但是,对于元素嵌入,我想扩展他的回答,因为他的解释对于用例来说似乎令人困惑且不完整。在 Tero Parviainen 的博客“A Guide to Transclusion in Angularjs”中,他找到了元素嵌入的根源,主要是为了延迟 UI 某些部分的链接和附件。
引用他的话:
了解元素嵌入
Let's now turn our attention to an alternative way you can use transclusion: Doing element transclusion with transclude: 'element'.
One use case for element transclusion is when you want to defer the linking and attachment for some part of your UI until something happens. Since element transclusion essentially removes part of the DOM and makes it available for you to put back using the transclusion function, you have control into when that happens.
For example, you might want to only link and attach part of the DOM after some condition on the parent scope becomes true: What we have here is essentially a simplified version of ngIf. If you look at the source code of ngIf, you should now be able to understand what it's doing: It's using element transclusion to conditionally link this part of the DOM only when the condition expression is true. This also explains why you see HTML comments in your DOM tree whenever ngIf is used. They're inserted by element transclusion.
当我在页面上查看源代码时,我会在 Chrome 开发工具的“元素”选项卡中看到这一点,但不明白它的来源。我也用 ng-repeat 看到了它。
Repeated Rendering with Element Transclusion. Another use case for element transclusion is if you want to link and attach part of the DOM several times.
For example, you could have a directive that iterates over an array and renders the DOM subtree again for each item in the array, also making each item available on the scope. This can all be done when we combine the element transclusion mechanism with the clone attach function, because then we can link a new clone for the DOM for each item: This is essentially a (hugely) simplified version of ngRepeat. The built-in ngRepeatdirective also uses element transclusion, though studying its source code is not quite as easy as with ngIf because of the various ways you can use ngRepeatand all the optimizations it contains. At the heart of it though, it's just an application of element transclusion and the clone attach function.
我觉得 Tero 关于元素使用 Transclusion 的报道比我想象的要好。