Eval 指令的参数 angular
Eval directive's parameters angular
我有这个 html 模板:
<div width-watcher>
<div parallax-bg parallax-active="!(tablet || mobile)">
...
</div>
</div>
width-watcher
公开了 3 个布尔值:移动设备、平板电脑和屏幕。这里没有指令选项。我想计算表达式 "!(tablet || mobile)"
以将其传递给我的第二个指令 parallax-bg
,以禁用移动设备上的视差。
我尝试了以下方法(在 parallax-bg
中):
- 使用
scope.$eval(attr.parallaxActive)
returns"undefined"
- 直接使用 scope.parallaxActive :
"&"
=> returns一个函数,当执行时returns "undefined"
"="
=> returns "undefined"
"@"
=> returns "!(tablet || mobile)"
而我运行没主意了。由于英语不是我的母语,我可能错过了 Google.
上的一些解决方案
这是我的背景视差指令的代码:
.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){
...
}
}
};
你的第一个方法 scope.$eval(attr.parallaxActive)
是正确的,但如果你将属性值绑定到你的指令范围,它将不起作用。
工作示例: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));
};
}
也就是说,我的建议是使用工厂策略将您的 widthWatcher
指令转换为服务。这样,您可以将它注入任何控制器、指令、过滤器或其他服务,并在不依赖范围的情况下确定屏幕类型。
工作示例: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());
};
}
更新
为了解决调用 parallaxBg
link 函数时未定义值的注释,我更新了 JSFiddle 以显示 link 函数的顺序打电话。
为了理解这是怎么回事,你需要理解how directives are compiled。
我有这个 html 模板:
<div width-watcher>
<div parallax-bg parallax-active="!(tablet || mobile)">
...
</div>
</div>
width-watcher
公开了 3 个布尔值:移动设备、平板电脑和屏幕。这里没有指令选项。我想计算表达式 "!(tablet || mobile)"
以将其传递给我的第二个指令 parallax-bg
,以禁用移动设备上的视差。
我尝试了以下方法(在 parallax-bg
中):
- 使用
scope.$eval(attr.parallaxActive)
returns"undefined"
- 直接使用 scope.parallaxActive :
"&"
=> returns一个函数,当执行时returns"undefined"
"="
=> returns"undefined"
"@"
=> returns"!(tablet || mobile)"
而我运行没主意了。由于英语不是我的母语,我可能错过了 Google.
上的一些解决方案这是我的背景视差指令的代码:
.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){
...
}
}
};
你的第一个方法 scope.$eval(attr.parallaxActive)
是正确的,但如果你将属性值绑定到你的指令范围,它将不起作用。
工作示例: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));
};
}
也就是说,我的建议是使用工厂策略将您的 widthWatcher
指令转换为服务。这样,您可以将它注入任何控制器、指令、过滤器或其他服务,并在不依赖范围的情况下确定屏幕类型。
工作示例: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());
};
}
更新
为了解决调用 parallaxBg
link 函数时未定义值的注释,我更新了 JSFiddle 以显示 link 函数的顺序打电话。
为了理解这是怎么回事,你需要理解how directives are compiled。