2013-12-21 68 views
1

試圖根據this blog post從angular-ui-bootstrap修飾typeahead指令並且遇到一些麻煩。我需要替換​​綁定(直到某些PR會修復它的行爲如預期),所以我想我可以獲取指令來裝飾,調用link.apply(this,arguments),然後再插入​​綁定,如圖所示在此代碼示例:Angular.js修飾的指令沒有得到指令範圍

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不存在(沒有定義)的錯誤 - 這意味着該指令原來的範圍並沒有真正運行 - 嘗試這種與其他變量從原始指令失敗並出現相同的錯誤。我該如何解決這個問題?

感謝您的幫助

回答

2

創建事先鍵入的內容內部子範圍。 望着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(); 
}); 

正如評論,matches和您嘗試訪問其他變量指出是對兒童的範圍,而不是範圍你」重新看。

由於子範圍在父母(originalScope)銷燬之前不會銷燬,因此您可以通過$$childHead訪問它。使用內部$$變量可能會有風險 - 但在Angular's scope documentation中討論過,因此希望這意味着他們打算保留此屬性。

的修復link.apply(this, arguments);後添加以下行,然後使用你childScope裝飾者:

childScope = scope.$$childHead; 

補充一點,這行現在將工作:

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

plunker