何时使用角度转换

时间:2016-01-25 05:31:36

标签: angularjs transclusion

我正在阅读角度转换,本页的一些示例: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>

这是userPost指令的HTML模板:

<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>

我想知道使用翻译的最佳案例?

3 个答案:

答案 0 :(得分:4)

要了解Transclusion,以及何时/如何使用它,您必须了解一下您尝试表示的DOM,以及角度指令如何在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有一席之地。 Transclusion允许元素的内部内容放置在模板中,ng-transclude指令存在的位置。

现在,翻译可能会变得非常棘手,特别是当你有一个嵌套在另一个指令的内部内容中的指令时,它可能非常强大。但是,如果您的指令在标记中的元素内没有内容,则不需要进行转换。有许多方法可以使用翻译,但从最核心的角度来看,他们最终都会回到这个概念。

答案 1 :(得分:1)

您可以使用transclude向您的指令中注入一堆html。创建指令的想法是,您可以使用可重复使用的一堆代码,您可以在应用程序的各个部分中使用这些代码。通过Transclusion,您可以从模板中进一步自定义指令的内容。

根据您的示例,通过翻译创建user-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个用户帖子。一个有帖子和用户喜欢,另一个有帖子,用户喜欢和评论。

答案 2 :(得分:0)

同一API提供了两个独立的功能:常规转换元素转换

对于常规转换,基本用例是:您希望将一些内容从一个模板包含或替换为另一个模板。使用常规转换有两种方法:ngTransclude指令和Transclusion Function。

以下是来自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>

转换功能

  

进行转换的第二种方法是使用transclude函数   在指令的post-link函数中提供。在下面的代码中,   link属性指向post-link函数。除非预先链接   函数是专门提供的,所有引用都是链接函数   参考后链接功能。查看下面的代码,看看如何   使用transclude函数可以实现相同的目标:

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);
      });
    }
  };
})
  

transclude函数传递一个回调参数   用于操纵克隆元素的函数。在上面的代码中,   回调函数将接收克隆的内容作为参数,然后   该函数将克隆的内容添加到DOM。执行   链接函数的结果导致以下HTML输出:

HTML代码

<div foo>
  <div>
      the template
      <div>Some Content Here</div>
  </div>
</div>

然而,对于Element transclusion,我想扩展他的答案,因为他的解释对于用例来说似乎令人困惑和不完整。在Tero Parviainen的博客“A Guide to Transclusion in Angularjs”中,他找到了元素转换的根源,主要是为了推断UI的某些部分的链接和附件。

引用他:

了解元素转换

  

现在让我们将注意力转向您可以使用的另一种方式   transclusion:使用transclude执行元素转换:&#39; element&#39;。

     

元素转换的一个用例是当你想推迟时   链接和附件的UI的某些部分,直到某些东西   发生。因为元素转换基本上删除了部分内容   DOM并使您可以使用转换回放   功能,你可以控制何时发生。

     

例如,你   可能只想在一些之后链接并附加DOM的一部分   父范围的条件变为真:我们在这里有什么   本质上是ngIf的简化版本。如果你看一下来源   ngIf的代码,你现在应该能够理解它在做什么:   它使用元素转换来有条件地链接这部分内容   仅当条件表达式为真时才使用DOM。这也解释了原因   每当使用ngIf时,您都会在DOM树中看到HTML注释。他们&#39;再   通过元素转换插入。

当我在页面上查看源代码时,我会在Chromes Dev Tools的Element选项卡中看到这些内容,但不知道它来自何处。我也用ng-repeat看到了它。

  

使用元素转换重复渲染。另一个用例   元素转换是指您想要链接和附加DOM的一部分   几次。

     

例如,您可以拥有一个迭代的指令   在数组上并再次为每个项目呈现DOM子树   数组,也使范围内的每个项目可用。这一切都可以   当我们将元素转换机制与克隆相结合时完成   附加函数,因为那时我们可以为DOM链接一个新的克隆   每个项目:这基本上是一个(非常)简化版本   ngRepeat。内置的ngRepeatdirective也使用了元素   虽然研究它的源代码并不是那么简单,但实际上并没有这么简单   使用ngIf因为各种方法可以使用ngRepeat和所有   它包含的优化。但它的核心是,它只是一个   元素转换的应用和克隆附加功能。

我觉得Tero关于使用Transclusion by element的报道比我说的要好。