我知道这是一个非常常见的问题,但我搜索了很多帖子,并没有找到解决问题的方法。
我的指令的目的是响应性地最小化侧栏。 为了做到这一点,我注册媒体查询并添加监听器以添加特定的类,但我有一个问题,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>
谢谢!
答案 0 :(得分:1)
好的我终于理解了我的错误!
我正在更新&#34; native&#34; Javascript监听器,我必须调用范围。$ apply()来更新范围。