嵌套的AngularJS指令......我在这里做错了什么?

时间:2013-09-06 02:29:11

标签: javascript angularjs angularjs-directive

所以,在过去的几个小时里,我一直在敲我的键盘试图找出如何解决这个问题:

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

进入这个:

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

使用此:http://jsfiddle.net/qBnDF/14/

由于某些奇怪的原因,如果我在scope-filter-item模板中加入scope-filter<div ng-transclude></div>条目只会被处理并与scope-filter.html相关联。

这个指令还有很多东西要做,但为了简单起见,我只会提取与实际问题无关的所有不必要的东西。

从我读到的有关指令的内容是,您应该能够使用require: '^thingToRequire'语法将控制器从父级传递给子级。然后,这应该将父控制器注入子控制器link方法。

不确定这里发生了什么。对不起,我现在更像是一个有角度的新手,这对我来说是一种伏都教/黑魔法。

非常感谢任何帮助!

2 个答案:

答案 0 :(得分: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 here

我从value删除了addScopeFilterItem参数,因为在此示例中不需要它。如果您出于某种原因需要它,我建议您将新属性添加到scopeFilterItem - value,或许 - 并从那里获取。

最后,您需要使用transclusion,因此Angular不会丢弃<scope-filter>标记的内容。查看这个小jsFiddle脚本,注意只有在启用了删除时才会呈现指令的内容。

答案 1 :(得分:0)

  

scope-filter-item条目仅被处理和关联   scope-filter如果我包含在   scope-filter.html模板

scope-filter-item无法在DOM中的任何位置调用链接功能。 ng-transclude做的是编译整个scope-filter并将其插入到DOM中,这使得代码可以正常工作。

根据您想要达到的目标,有以下几种选择:

  1. 遵循Michael Benford的建议。
  2. 以其他方式提供数据,而不是scope-filter-item标记。例如,通过ng-model指令公开items对象。这会更容易,但我不知道你的决定背后的原因,所以这可能不合适。
  3. 删除scopeFilterItem指令,并通过scopeFilter
  4. 中的手动转换获取项目

    Working example

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

    This article提供了几个翻译示例,您可能会觉得它很有用。