自定义ng-repeat attr指令和transcluding元素

时间:2015-06-03 20:11:29

标签: angularjs angularjs-directive coffeescript angularjs-ng-repeat angularjs-ng-transclude

好的,我发誓我已经搜遍了所有的SO以获得答案。我发现的每个答案几乎,但不完全,完全不是我正在寻找的。

目标

我正在尝试编写一些指令,让我干掉我展示集合的方式。最终目标是能够在视图或其他指令中执行以下操作:

<md-grid-tile index='event' index-by='isPublic' index-key='true'>
  <md-grid-tile-header>{{event.name}}</md-grid-tile-header>
  <md-grid-tile-footer>
    <profile-card index='eventOwner' index-by='event_id' index-key='event.$id' collection='profile'>
      arbitrary transcluded content that uses {{profile}}
    </profile-card>
  </md-grid-tile-footer>
</md-grid-tile>

md-grid-tile-*都来自棱角分明的材料,并且喜欢用内容来抄写东西。 profile-card是一个包含被转换内容的任意自定义指令。例如。我有一张显示个人资料信息的公用卡,但我想在其上放置不同的操作按钮,具体取决于我放置它的位置。

我正在尝试创建index指令,它将像一个非常集中的ng-repeat。在这个例子中:

  • md-grid-tile元素上的attrs告诉它重复每个event isPublic true
  • profile-card元素上,它会找到所有eventOwner个对象,event_id与包含元素的event.$id匹配。然后,它将重复那些profile个对象引用的eventOwner个对象。

问题

我在连接数据源方面没有遇到任何问题,我遇到的问题是:

  • 在正确的位置在DOM中创建多个元素
  • 重复转换内容的元素

出于代码示例的目的,我简化了数据源。 mockProvider将替换为基于index-* attrs创建集合的服务。

尝试#1

.directive 'index', ['mockProvider', (mockProvider)->
  restrict: 'A'
  priority: 1
  compile: (el,attrs)->

    el.attr 'ng-repeat', 'item in collection'

    post: (scope,el,attrs,ctrl,transclude)->
      scope.collection = mockProvider
]

我仍然无法弄清楚为什么我不能让这种方法起作用。 ng-repeat attr被正确附加,但没有重复。

尝试#2

.directive 'index', ['mockProvider', (mockProvider)->
  restrict: 'A'
  priority: 1 # tried with 1, 1001, -1000
  compile: (el,attrs)->
    post: (scope,el,attrs,ctrl,transclude)->
      scope.collection = mockProvider
      newEl = angular.element el[0].outerHTML
      newEl.attr 'ng-repeat', 'foo in [1,2,3]'
      newEl.removeAttr 'pb-index'
      el.replaceWith $compile(newEl[0].outerHTML)(scope)
]

这重复了一堆东西,但随后爆炸:[ngTransclude:orphan] Illegal use of ngTransclude directive in the template! No parent directive that requires a transclusion found.似乎重新编译以某种方式丢失了被抄送的内容?我也看到其他SO评论由于效率低下而发出警告。

尝试#3

.directive 'index', ['mockProvider', (mockProvider)->
  restrict: 'A'
  priority: 1001
  compile: (el,attrs)->
    post: (scope,el,attrs,ctrl,transclude)->
      el.html ""
      scope.collection = mockProvider
      scope.$watchCollection 'collection', (collection)->
        for item,index in collection
          childScope = scope.$new()
          childScope.item = item
          transclude childScope, (newElement)->
            el.append newElement

最后,我尝试了ng-repeat的天真重新实现。这已经变得最接近,但仍然不起作用,并且需要更多代码才能使其与ng-repeat的性能/功能相匹配。

HOW ???

我完全走错了路吗?有一个简单的方法吗?

0 个答案:

没有答案