1

So, I've been banging my head against my keyboard for the past few hours trying to figure out how to turn this:

<scope-filter label="Sort by" type="sort">  
    <scope-filter-item key="recent">Recent Activity</scope-filter-item>  
    <scope-filter-item key="influence">Influence</scope-filter-item>
    <scope-filter-item key="loyalty">Loyalty</scope-filter-item>
    <scope-filter-item key="followers">Followers</scope-filter-item>
    <scope-filter-item key="visits">Visits</scope-filter-item>
</scope-filter>

Into this:

<div>
  <label>Sort By:</label>
  <ul>
    <li>Recent Activity</li>
    <li>Influence</li>
    <li>Loyalty</li>
    <li>Followers</li>
    <li>Visits</li>
  </ul>
</div>

Using this: http://jsfiddle.net/qBnDF/14/

For some odd reason, scope-filter-item entries are only being processed and associated with scope-filter if I include <div ng-transclude></div> within the scope-filter.html template.

There are quite a few more things this directive is going to do, but to keep things simple, I'll just extract all the unnecessary stuff unrelated to the actual problem.

From what I've read about directives is that you should be able to pass a controller from the parent to the child by using the require: '^thingToRequire' syntax. This then should inject the parent controller into the child controllers link method.

Not really sure what's going on here. Sorry, I'm more of an angular novice at the moment and this is kind of voodoo / black magic to me.

Any help would be greatly appreciated!

4

2 回答 2

2

看看这是不是你想要的:

HTML

<script type="text/ng-template" id="scope-filter.html">
  <div>
    <label>{{ label }}:</label>            
      <ul ng-transclude></ul>           
  </div>
</script>

Javascript

sandbox.directive('scopeFilterItem', function () {
  return {
    restrict: 'E',
    require: '^scopeFilter',
    transclude: true,
    template: '<li ng-transclude></li>',
    link: function (scope, iElement, iAttrs, scopeFilter) {
        scopeFilter.addScopeFilterItem(iAttrs.key)
    }
  }
});

jsFiddle在这里

我删除了这个value参数,addScopeFilterItem因为在这个例子中不需要它。如果您出于某种原因需要它,我建议您向scopeFilterItem-添加一个新属性value,也许 - 并从那里获取它。

最后,您需要使用嵌入,这样 Angular 就不会丢弃<scope-filter>标签的内容。查看这个小的jsFiddle脚本,并注意指令的内容只有在启用嵌入时才会呈现。

于 2013-09-06T04:24:48.143 回答
0

如果我包含在 scope-filter.html 模板中,则范围过滤器条目只会被处理并与范围过滤器相关联

scope-filter-item' 不会调用链接函数而不存在于 DOM 中的任何位置。ng-transclude所做的是编译整个并将scope-filter其插入到 DOM 中,这使得代码工作。

根据您想要实现的目标,有几种选择:

  1. 听从迈克尔本福德的建议。
  2. 以其他方式提供数据而不是scope-filter-item标签。例如,通过ng-model指令公开 items 对象。这会更容易,但我不知道你决定背后的原因,所以这可能不适合。
  3. 删除scopeFilterItem指令并通过手动嵌入获取项目scopeFilter

工作示例

JavaScript

sandbox.directive('scopeFilter', function () {
    return {
        transclude: true,
        replace: true,
        restrict: 'E',
        templateUrl: 'scope-filter.html',
        scope: {
            label: '@label',
            type: '@type'
        },
        controller: function ($scope, $transclude) {
            $scope.items = [];
            $transclude(function (clone) {
                angular.forEach(clone, function(item) {
                    if (item.tagName !== "SCOPE-FILTER-ITEM") return;
                    $scope.items.push({
                        key: item.getAttribute("key"),
                        value: item.innerText
                    });
                });
            });
        }
    }
})

HTML

<script type="text/ng-template" id="scope-filter.html">
    <div>
        <label>{{ label }}:</label>
        <ul>
            <li ng-repeat="item in items">{{ item.key }}</li>
        </ul>
    </div>
</script>

本文提供了几个嵌入示例,您可能会发现它很有用。

于 2013-09-06T05:18:29.590 回答