I have this html template :
<div width-watcher>
<div parallax-bg parallax-active="!(tablet || mobile)">
...
</div>
</div>
width-watcher
exposes 3 boolean values: mobile, tablet and screen. No directive options here. I want to evaluate the expression "!(tablet || mobile)"
to pass it to my second directive parallax-bg
, to disable parallax on mobile devices.
I've tried the following (in parallax-bg
):
scope.$eval(attr.parallaxActive)
returns "undefined"
"&"
=> returns a function, when executed returns "undefined"
"="
=> returns "undefined"
"@"
=> returns "!(tablet || mobile)"
And I ran out of ideas. As english isn't my native language, I've probably missed some solutions on Google.
This is the code of my background-parallax directive :
.directive('parallaxBackground', function($window) {
return {
transclude: true,
template: '<div ng-transclude></div>',
scope: {
parallaxRatio: '@',
parallaxOffset: '@',
},
link: function(scope, elem, attrs) {
var scopeActive = scope.$eval(attrs.parallaxActive);
var ...
if(scopeActive){
...
}
}
};
Your first method, scope.$eval(attr.parallaxActive)
is correct, but won't work if you bind the attribute value to your directive's scope.
Working example: JSFiddle
angular.module('myApp').directive(function() {
return {
link: postLink,
template: '<ng-transclude></ng-transclude>',
transclude: true
};
function postLink(scope, iElement, iAttrs) {
alert(scope.$eval(iAttrs.parallaxActive));
};
}
That said, my recommendation would be to turn your widthWatcher
directive into a service using the factory strategy. This way, you can just inject it into any controller, directive, filter or other service and determine the screen type without relying on scope.
Working example: JSFiddle
angular.module('myApp', [])
.factory('$widthWatcher', widthWatcherFactory)
.directive('parallaxBg', parallaxBgDirective)
;
function widthWatcherFactory() {
return {
isMobile: isMobile,
isScreen: isScreen,
isTablet: isTablet
};
function getWidth() {
return window.innerWidth || document.body.clientWidth;
}
function isMobile() {
return getWidth() < 600;
}
function isScreen() {
return getWidth() > 960;
}
function isTablet() {
return !isMobile() && !isScreen();
}
}
function parallaxBgDirective($widthWatcher) {
return {
link: postLink,
template: '<ng-transclude></ng-transclude>',
transclude: true
};
function postLink(scope, iElement, iAttrs) {
alert($widthWatcher.isScreen());
};
}
UPDATE
To address the comment about values being undefined when the parallaxBg
link function is called, I updated the JSFiddle to show the order in which link functions are called.
In order to understand what is going on, you need to understand how directives are compiled .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.