2015-09-29 173 views
1

我知道這是一個很常見的問題,但我搜索了很多帖子,並沒有找到解決我的問題。角JS指令隔離範圍雙向綁定不起作用

我的指令的目的是最大限度地減少側邊欄響應。 爲了做到這一點,我註冊了媒體查詢並添加了監聽器來添加特定的類,但是我在使用isMinimized進行雙向綁定時沒有更新父範圍。

實際上,它在初始化時更新父範圍,當第一次調用_mqlMinimizeListener(mql***Devices);_mqlUnminimizeListener(mql***Devices);時(檢測屏幕的初始大小),但在值不再更新之後。

這裏是我的指令:

angular.module('app.minimizableSideBar').directive('minimizableSideBar', 
[ 
    '$window', 
    function($window) { 
     return { 
      restrict: 'A', 
      scope: { 
       minimizeOn: '@', 
       addClass: '@', 
       isMinimized: '=' 
      }, 
      link: function(scope, element) { 

       /** 
       * Initialize the directive and handle behavior regarding provided params 
       */ 
       var init = function() { 

        if (!_validParams()) { 
         return; 
        } 

        // If browser is recent 
        if ($window.matchMedia) { 
         if (scope.minimizeOn === 'object') { 
          _handleRangeBreakpoint(); 
         } else { 
          scope.minimizeOn = parseInt(scope.minimizeOn); 
          _handleSimpleBreakpoint(); 
         } 
        } else { 
         // If browser outdated, we fall back on innerWidth 
         scope.$watch(function() { 
          return $window.innerWidth; 
         }, function(value) { 
          if (value < scope.minimizeOn) { 
           element.addClass(scope.addClass); 
          } else { 
           element.removeClass(scope.addClass); 
          } 
         }); 
        } 

        // We handle external minimization (i.e. the user want to minimize/un-minimize 
        // the sidebar by clicking on a button 
        scope.$watch('isMinimized', function(value) { 
         if (value) { 
          element.addClass(scope.addClass); 
         } else { 
          element.removeClass(scope.addClass); 
         } 
        }); 
       }; 

       /** 
       * Check params validity 
       * 
       * @returns {Boolean} true if params are valid, false otherwise 
       * @private 
       */ 
       var _validParams = function() { 
        if (scope.addClass && 
         scope.minimizeOn) { 

         if (scope.minimizeOn === 'object' && 
          (!scope.minimizeOn.lowerSize || 
          !scope.minimizeOn.upperSize || 
          Number.isNaN(scope.minimizeOn.lowerSize) || 
          Number.isNaN(scope.minimizeOn.upperSize))) { 
          return false; 
         } else if (Number.isNaN(scope.minimizeOn)) { 
          return false; 
         } 
         return true; 
        } 
       }; 

       /** 
       * Listener for minimizing action 
       * 
       * @param {MediaQueryList} mql a media query listener 
       */ 
       var _mqlMinimizeListener = function(mql) { 
        if (mql.matches) { 
         element.addClass(scope.addClass); 
         scope.isMinimized = true; 
        } 
       }; 

       /** 
       * Listener for unminimizing action 
       * 
       * @param {MediaQueryList} mql a media query listener 
       */ 
       var _mqlUnminimizeListener = function(mql) { 
        if (mql.matches) { 
         element.removeClass(scope.addClass); 
         scope.isMinimized = false; 
        } 
       }; 

       /** 
       * Handle Range breakpoint with lower size and higher size 
       * 
       * @private 
       */ 
       var _handleRangeBreakpoint = function() { 
        var lowerSize = parseInt(scope.minimizeOn.lowerSize); 
        var upperSize = parseInt(scope.minimizeOn.upperSize); 

        // Handle screen sizes 
        //-- In the range 
        var mqlRangeDevices = $window.matchMedia('screen and (min-width: ' + lowerSize + ' px) and (max-width: ' + upperSize + 'px)'); 
        mqlRangeDevices.addListener(_mqlMinimizeListener); 
        _mqlMinimizeListener(mqlRangeDevices); 

        //-- Out of the range 
        var mqlInfDevices = $window.matchMedia('screen and (max-width: ' + lowerSize - 1 + 'px)'); 
        mqlInfDevices.addListener(_mqlUnminimizeListener); 
        _mqlUnminimizeListener(mqlInfDevices); 

        var mqlSupDevices = $window.matchMedia('screen and (min-width: ' + (upperSize + 1) + 'px)'); 
        mqlSupDevices.addListener(_mqlUnminimizeListener); 
        _mqlUnminimizeListener(mqlSupDevices); 
       }; 

       /** 
       * Handle simple breakpoint (i.e. when mnimizeOn only contains string for one size) 
       * 
       * @private 
       */ 
       var _handleSimpleBreakpoint = function() { 
        var mqlInfDevices = $window.matchMedia('screen and (max-width: ' + scope.minimizeOn + 'px)'); 
        mqlInfDevices.addListener(_mqlMinimizeListener); 
        _mqlMinimizeListener(mqlInfDevices); 

        var mqlSupDevices = $window.matchMedia('screen and (min-width: ' + (scope.minimizeOn + 1) + 'px)'); 
        mqlSupDevices.addListener(_mqlUnminimizeListener); 
        _mqlUnminimizeListener(mqlSupDevices); 
       }; 

       init(); 
      } 
     }; 
    } 
] 
); 

,這裏是HTML標記:

<div class="sidebar navbar-collapse collapse sidebar-navbar-collapse" 
    data-minimizable-side-bar 
    data-minimize-on="992" 
    data-add-class="sidebar-minimized" 
    data-is-minimized="sidebar.isMinimized"> 
</div> 

謝謝!

回答

1

好吧我終於明白了我的錯誤!

由於我從「native」Javascript偵聽器更新範圍,所以我必須調用scope。$ apply()來更新範圍。

相關問題