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>
謝謝!