如何通过在角递归指令功能的参考? [英] How to pass a function reference in a recursive directive in Angular?

查看:129
本文介绍了如何通过在角递归指令功能的参考?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这样的指令:

app.directive('recursiveListItem', ['$http', 'RecursionHelper', function ($http, RecursionHelper) {
    return {
        restrict: 'E',
        scope: {
            parent: '=',
            onNodeClick: '&',
        },
        compile: function (element, attributes) {
            return RecursionHelper.compile(element);
        },
        template:
            '<div class="list-group-item-heading text-muted parent "> \
                <input type="checkbox" data-ng-click="visible = !visible" id="{{parent.Name}}">\
                <label for="{{parent.Name}}">&nbsp;&nbsp;</label>\
                <a href="javascript:void(0)" data-ng-click="onNodeClick({node: parent})">{{parent.Name}}</a> \
            </div> \
            <ul data-ng-if="parent.Children.length > 0" data-ng-show="visible"> \
                <li ng-repeat="child in parent.Children"> \
                    <recursive-list-item data-parent="child" data-on-node-click="onNodeClick"></recursive-list-item> \
                </li> \
            </ul>',     
    };
}]);

和这里是助手:

app.factory('RecursionHelper', ['$compile', function ($compile) {
    var RecursionHelper = {
        compile: function (element) {
            var contents = element.contents().remove();
            var compiledContents;
            return function (scope, element) {
                if (!compiledContents) {
                    compiledContents = $compile(contents);
                }
                compiledContents(scope, function (clone) {
                    element.append(clone);
                });
            };
        }
    };

    return RecursionHelper;
}]);

一切工作就像一个魅力,但我没有得到我的的节点点击工作。对于一切的根源项目'回调'工作正常,但是从那里,所有的孩子将不会触发回调。我认为这是与传递函数引用到下一个孩子在模板中。

Everything works like a charm, but I don't get my on-node-click to work. For the all the root items the 'callback' works fine, but from there on, all the children won't fire the callback. I think it has something to do with passing the function reference to the next child in the template.

我也试过数据的节点点击=onNodeClick(节点),但这并不能工作。

I've also tried data-on-node-click="onNodeClick(node)", but that doesn't work either.

有人不知道如何该函数引用传递到子节点?

Does someone know how to pass the function reference to the child nodes?

推荐答案

作为其有用的铅看'和;'其中文档描述是这样的:

Underlying Issue

As a lead in its helpful to look at '&' which the docs describe this way:

&安培;或放大器; attr指示 - 提供了一种在上下文中执行一个前pression
  父范围。

& or &attr - provides a way to execute an expression in the context of the parent scope.

通常它需要通过一个从孤立的范围内传递数据
  前pression和到母体范围,这可以通过使地图进行
  本地变量名和值进入前pression包装FN。对于
  例如,如果前pression是增量(量),那么我们可以指定
  

Often it's desirable to pass data from the isolated scope via an expression and to the parent scope, this can be done by passing a map of local variable names and values into the expression wrapper fn. For example, if the expression is increment(amount) then we can specify the amount value by calling the localFn as localFn({amount: 22})

为了实现这一点,是通过一个&放大器传递函数; 被包裹在另一个函数 parentGet()。我们可以通过查看点击处理函数变量的内容在行动中看到这一点。首先,之前它传递到&安培; 这是因为我们预期:

In order to achieve this the function that is passed through an & is wrapped in another function parentGet(). We can see this in action by looking at the contents of the click handler function variable. First, before it's passed into the & it's as we'd expect:

function (node) {
    console.log("called with ",node);
} 

不过,那么,你的指令里面,通过合格后'和;',它看起来像这样:

But, then, inside your directive, after passing through '&', it looks like this:

function (locals) {
     return parentGet(scope, locals);
} 

因此,而不是直接引用你的点击处理函数,这也是我们将同时使用父范围和任何当地人适用于您的函数的调用,你通过在

So instead of a direct reference to your click handler function it is now a call that will apply your function using both the parent scope and any locals which you pass in.

问题是,从我可以告诉,因为我们窝,往下该范围内可变不断得到更新以新的嵌套父范围。这不是对我们有好处。我们要执行上下文是顶级的范围在哪里你的点击处理程序。否则,我们失去了参考的功能 - 正如我们看到的情况。

The problem is that, from what I can tell, as we nest down that scope variable keeps getting updated to the new nested parent scope. That's not good for us. We want the execution context to be that top scope where your click handler is. Otherwise we lose reference to your function- as we see happening.

为了解决这个问题,我们保持一个参考原有的功能(即不是由 parentGet拖累()当我们窝向​​下)。然后,当我们通过它,在 parentGet()使用的范围是一个与它的点击处理函数。

To fix this we keep a reference to the original function (that isn't encumbered by parentGet() as we nest down). Then when we pass it in, the scope used in parentGet() is the one with click handler function on it.

首先,让我们使用不同的名称比您将使用该参数的实际功能。我设置了像这样 $ scope.onNodeClickFn =功能(节点)功能{...}

First let's use a different name for the actual function than you'll use for the parameter. I set up the function like so $scope.onNodeClickFn = function(node) {...}

然后我们做出改变3:

1)添加第二个范围的变量( topFunc

1) Add a second scope variable (topFunc):

scope: {
          onNodeClick: '&',
          topFunc: '='
       }

onNodeClick 是包装的函数(包括范围参数)。和 topFunc 是解开功能(请注意,我们通过在使用 = 所以它的基准的基准功能缺席包装,&放大器; 适用)

onNodeClick is the wrapped function (including scope parameter). And topFunc is a reference to the unwrapped function (note that we pass that in using = so it's a reference to the function absent the wrapper that & applies).

2)在顶层,我们同时通过函数的引用。

2) At the top level, we pass both function references in.

<recursive-list-item on-node-click="onNodeClickFn(node)" top-func="onNodeClickFn" parent=parent ></recursive-list-item>

(注意缺少()在顶FUNC 参数。)

3)传递新的 topFunc 参数到模板:

3) Pass the new topFunc parameter in to the template:

<recursive-list-item data-parent="child" data-on-node-click="topFunc(node)" top-func="topFunc"></recursive-list-item> \

因此,我们现在保持一个参考,在每一个嵌套的范围,原有的功能,并使用该模板

您可以看到它在此琴工作: http://jsfiddle.net/uf6Dn/9/

You can see it working in this fiddle: http://jsfiddle.net/uf6Dn/9/

这篇关于如何通过在角递归指令功能的参考?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆