Angular.js装饰指令没有得到指令范围 [英] Angular.js decorated directive doesn't get the directive scope

查看:174
本文介绍了Angular.js装饰指令没有得到指令范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

试图根据从角UI的引导装点预输入指令这个博客帖子并运行了一些麻烦。我需要更换的keydown 绑定(直到一些公关会解决它像预期的那样),所以我想我可以取指令来装饰,link.apply致电(此,参数),然后只需插入的keydown 再结合如图所示,在这个code例如:

trying to decorate typeahead directive from angular-ui-bootstrap according to this blog post and running into some trouble. I need to replace the keydown binding (until some PR would fix it to behave as expected), so I figured I could fetch the directive to decorate, call link.apply(this, arguments) and then just insert the keydown binding again as illustrated in this code example:

angular.module('ui.bootstrap').config(function($provide)
{
    $provide.decorator('typeaheadDirective', function($delegate)
    {
        var directive = $delegate[0]; //get the current directive with that name;
        //console.log('directive', directive) // I do get the directive here, just checking

        var link = directive.link; //getting the current link function. in which we would like to replace the keybinding
        //console.log('link:', link)

        directive.compile = function()
        {
            return function(scope, element, attrs)
            {
                link.apply(this, arguments);
                //element.unbind('keydown');

                element.bind('keydown', function(evt)
                {
                    //typeahead is open and an "interesting" key was pressed

                    console.log('scope matches', scope);
                    if (scope.matches.length === 0 || HOT_KEYS.indexOf(evt.which) === -1)
                    {
                        //@alon TODO:check this
                        return;
                    }

                    evt.preventDefault();

                    if (evt.which === 40)
                    {
                        scope.activeIdx = (scope.activeIdx + 1) % scope.matches.length;
                        scope.$digest();
                    }
                    else if (evt.which === 38)
                    {
                        scope.activeIdx = (scope.activeIdx ? scope.activeIdx : scope.matches.length) - 1;
                        scope.$digest();
                    }
                    else if (evt.which === 13 || evt.which === 9)
                    {
                        if (scope.activeIdx !== -1 && scope.activeIdx !== 0)
                        {
                            scope.$apply(function()
                            {
                                scope.select(scope.activeIdx);
                            });

                        }
                        else
                        {
                            evt.stopPropagation();
                            resetMatches();
                            scope.$digest();
                        }
                    }
                    else if (evt.which === 27)
                    {
                        evt.stopPropagation();
                        resetMatches();
                        scope.$digest();
                    }
                });
            };
        };

        return $delegate;
    });
});

但我得到那个指示scope.matches不存在(没有定义)的错误 - 这意味着该指令原来的范围并没有真正运行 - 从原来的指令,其他变量尝试这一失败,并同样的错误。我该如何解决呢?

but I getting errors that indicate that scope.matches doesn't exist(isn't defined) - meaning that the directive original scope doesn't really run - trying this with other variables from the original directive fail with the same error. How can I fix that?

感谢您的帮助。

推荐答案

键盘缓冲创建内部子范围。
  纵观<一个href=\"https://github.com/angular-ui/bootstrap/blob/ea053b1991424c57536ccb19948ed1e74d3542ed/src/typeahead/typeahead.js\"相对=nofollow>预输入源:

Typeahead creates an internal child scope. Looking at the typeahead source:

您会看到这一点:

//create a child scope for the typeahead directive so we are not polluting original scope
//with typeahead-specific data (matches, query etc.)

var scope = originalScope.$new();

originalScope.$on('$destroy', function(){
   scope.$destroy();
});

正如评论指出,匹配和您尝试访问其他变量都在这个孩子的范围,而不是你要找的范围。

As noted in the comment, matches and the other variables you are trying to access are on that child scope instead of the scope you're looking on.

由于该子范围不被破坏,直到父( originalScope )被破坏,你可以通过 $$ childHead 。它可以冒险使用内部 $ 变量 - 但它在的角的范围文档所以希望这意味着他们打算围绕保持这个属性。

Since that child scope isn't destroyed until the parent (originalScope) is destroyed you can access it via $$childHead. It can be risky to use internal $$ variables- but it's discussed in Angular's scope documentation so hopefully that means they intend to keep this property around.

的修复是在来添加以下行link.apply(这一点,参数); ,然后用 childScope 在你装饰:

The fix is to add the following line after link.apply(this, arguments); and then use childScope in you decorator:

childScope = scope.$$childHead;

补充一点,这行现在将工作:

Add that and this line will now work:

console.log('scope matches', childScope.matches)

plunker

这篇关于Angular.js装饰指令没有得到指令范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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