ng 使用自定义指令重复

Posted

技术标签:

【中文标题】ng 使用自定义指令重复【英文标题】:ng repeat with custom directive 【发布时间】:2016-08-25 01:08:24 【问题描述】:

我正在尝试使用另一个自定义元素读取 ng-repeat 在元素上设置的属性:

<div foo ng-repeat="img in [image: 'images/img1.jpg', text: 'some text',image: 'images/img2.jpg', text: 'some text']">
    <img ng-src="img.image"/>
    <p>img.text</p>
</div>

app.directive('foo',function() 
  return 
    restrict : 'A',
    scope: ,
    link:function (scope, element, attrs) 
      var imageNode = element.find('img');
      var textNode = element.find('p');

      var image = 
        url: imageNode.prop('src'),
        text: textNode.html()
      ;

      console.log(image);
    
  ;
);

因为ng-repeat在自定义指令之前运行,所以在'foo'的链接函数启动时,DOM应该插入两个元素。在这种情况下,'foo'的链接函数应该触发两次将元素作为 ng-repeat 插入的 DOM。

问题在于imageNode.prop('src'); 的值是“img.image”,而不是表达式的求值。

谁能帮我了解幕后到底发生了什么。

Plunker 示例 - https://plnkr.co/edit/E9JHhZUf2h7B6FVeXRK4?p=preview

编辑

上面的例子很简单,但我想了解的是指令执行的流程。有多种方法可以将数据传递给 foo 指令,但这不是最终目标。

根据我的理解,由于 ng-repeat 和 foo 是在同一个元素上定义的,所以执行顺序会是 1) 编译 ng-repeat 因为 ng-repear 的优先级为 1000 2) foo 的编译,因为 foo 的默认优先级为 0 3) foo 的链接,因为链接以相反的优先级顺序执行 4) ng-repeat的链接

由于 ng-repeat 使用 transclude,它在编译阶段吸出 DOM,并在其链接阶段再次添加。

如果是这样的话,在 ng-repeat 的链接之前执行的 foo 的链接函数应该只有 transclude 插入的注释作为其元素,因为尚未添加 DOM。 但事实并非如此。我可以访问 ng-repeat 在 foo 的链接阶段添加的两个新添加的 DOM 元素。我错过了什么?

另外,如果我没记错的话,表达式是在链接阶段评估的,所以如果在链接阶段发生的 ng-repeat 重新插入新元素,那么表达式也应该被评估并且 img.text 应该在 ng-repeat 的链接阶段转换为 "some text" 没有发生但是当我做 element[0] 时我可以查看值 image.text 被替换。 我又错过了什么吗?

【问题讨论】:

您应该使用 attrs 值来提取绑定到给定 DOM 元素的数据。 【参考方案1】:

您可以将指令中的图像数据作为属性传递

<div foo data='obj' ng-repeat="img in [image: 'images/img1.jpg', text: 'some text',image: 'images/img2.jpg', text: 'some text']">
    <img ng-src="img.image" />
    <p>img.text</p>
 </div>




app.directive('foo',function()
  return
    restrict : 'A',
    scope:,
    link:function(scope,element,attrs);

      var image = ;
      image.url = attrs.data.image
      image.text = attrs.data.text
      console.log(image);
    
  
);

【讨论】:

感谢您的回复,但目的不仅仅是传递数据,而是了解指令执行流程。我已经编辑了上述问题以添加更多详细信息【参考方案2】:

如果您只是尝试传入 url 和文本,为什么不将它们添加到范围中?

只需将 html 更改为:

  <div foo text=img.text image-url=img.image ng-repeat="img in [image: 'images/img1.jpg', text: 'some text',image: 'images/img2.jpg', text: 'some text']">

和 :

  app.directive('foo',function()
  return
    restrict : 'A',
    scope:
      text: '@',
      imageUrl: '@'
    ,
    link:function(scope,element,attrs);

      console.log(scope.text);
      console.log(scope.imageUrl);
    
  
);

查看修改后的 plunkr:https://plnkr.co/edit/0gw7uom9BGjFGJQ9e20E?p=preview

【讨论】:

感谢您的回复,但目的不仅仅是传递数据,而是了解指令执行流程。我已经编辑了上述问题以添加更多详细信息 @YatinGera 你可能会考虑发布一个不同的问题,因为你问的是一个完全不同的问题:)【参考方案3】:

如果你想将重复的数据传递给一个属性并在指令中使用它,试试这样

<div foo imgdata="img" ng-repeat="img in [image: 'images/img1.jpg', text: 'some text',image: 'images/img2.jpg', text: 'some text']">
    <img ng-src="img.image" />
    <p>img.text</p>
 </div>


app.directive('foo',function()
  return
    restrict : 'A',
    scope:
        imgdata: '='
    ,
    link:function(scope,element,attrs);

      console.log(scope.imgdata);
    
  
);

这个fiddle 指明了方向

希望对你有帮助

【讨论】:

感谢您的回复,但目的不仅仅是传递数据,而是了解指令执行流程。我已经编辑了上述问题以添加更多详细信息

以上是关于ng 使用自定义指令重复的主要内容,如果未能解决你的问题,请参考以下文章

通过自定义指令进行 ng-grid 分页

ng 指令的自定义使用

AngularJS:如何使用自定义指令来取代ng-repeat

Angular 自定义指令在 ng-repeat 中使用 if 条件

编写自定义指令以在 AngularJS (TypeScript) 中向 ng-options 添加工具提示

走进AngularJs自定义指令----(下)