用自定义指令

时间:2016-04-29 18:59:43

标签: angularjs angularjs-directive angularjs-scope angularjs-ng-repeat angular-directive

我正在尝试使用另一个自定义元素读取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在自定义指令之前运行,因此在&#39; foo&#39;的链接功能之前,应该使用2个元素插入DOM。踢进去。在这种情况下,&#39; foo&#39;的链接功能。应该通过ng-repeat将元素作为插入的DOM激发两次。

问题是imageNode.prop('src');的值为&#34; {{img.image}}&#34;而不是对表达的评价。

任何人都可以帮助我理解幕后发生了什么。

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

EDIIT

上面的例子是微不足道的,但我想要理解的是指令执行的流程。有一些方法可以将数据提供给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。 但事实并非如此。我可以在foo的链接阶段访问由ng-repeat添加的两个新添加的DOM元素。我错过了什么?

另外,如果我没有错,那么在链接阶段会对表达式进行评估,所以如果在链接阶段通过ng-repeat重新插入新元素,那么表达式也应该被评估并且 { {img.text}} 应该在ng-repeat的链接阶段转换为&#34;某些文字&#34; ,这是没有发生但是当我做元素[0 ]那就是我可以看到被替换的值{{image.text}}。 我又错过了什么吗?

3 个答案:

答案 0 :(得分: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);
    }
  }
});

答案 1 :(得分:0)

如果您只是尝试传递网址和文字,为什么不将它们添加到范围内?

只需将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'}]">

和dierctive:

  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

答案 2 :(得分:0)

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

<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显示方式

希望这会有所帮助