簡體   English   中英

Angular.js裝飾指令未獲取指令范圍

[英]Angular.js decorated directive doesn't get the directive scope

試圖根據此博客文章從angular-ui-bootstrap裝飾typeahead指令,並遇到了一些麻煩。 我需要替換keydown綁定(直到某些PR可以將其修復為預期的行為為止),因此我認為可以提取該指令進行裝飾,調用link.apply(this,arguments),然后再次插入keydown綁定,如圖所示在此代碼示例中:

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不存在(未定義)的錯誤-這意味着指令原始范圍實際上並未運行-使用原始指令中的其他變量嘗試此操作會失敗,並出現相同的錯誤。 我該如何解決?

謝謝您的幫助

提前輸入將創建內部子范圍。 預先輸入的來源

您會看到以下內容:

//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();
});

如注釋中所述, matches和您嘗試訪問的其他變量都在該子范圍內,而不是您要查找的范圍內。

由於直到父級( originalScope )被銷毀之前,該子級作用域才被銷毀,因此您可以通過$$childHead訪問它。 使用內部$$變量可能會有風險-但Angular范圍文檔中對此進行了討論,因此希望這意味着他們打算保留此屬性。

解決方法是在link.apply(this, arguments);之后添加以下行link.apply(this, arguments); 然后在裝飾器中使用childScope

childScope = scope.$$childHead;

添加它,此行現在將起作用:

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

plunker

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM