简体   繁体   English

Eval指令的参数angular

[英]Eval directive's parameters angular

I have this html template : 我有这个html模板:

<div width-watcher>
    <div parallax-bg parallax-active="!(tablet || mobile)">
        ...
    </div>
</div>

width-watcher exposes 3 boolean values: mobile, tablet and screen. width-watcher公开了3个布尔值:移动设备,平板电脑和屏幕。 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. 我想评估表达式"!(tablet || mobile)"并将其传递给第二个指令parallax-bg ,以禁用移动设备上的视差。

I've tried the following (in parallax-bg ): 我已经尝试了以下(在parallax-bg ):

  • Use scope.$eval(attr.parallaxActive) returns "undefined" 使用scope.$eval(attr.parallaxActive)返回"undefined"
  • Use directly scope.parallaxActive with : 直接将scope.parallaxActive与以下项配合使用:
    • "&" => returns a function, when executed returns "undefined" "&" =>返回一个函数,执行时返回"undefined"
    • "=" => returns "undefined" "=" =>返回"undefined"
    • "@" => returns "!(tablet || mobile)" "@" =>返回"!(tablet || mobile)"

And I ran out of ideas. 而且我用尽了所有的想法。 As english isn't my native language, I've probably missed some solutions on Google. 由于英语不是我的母语,所以我可能错过了Google上的一些解决方案。

This is the code of my background-parallax directive : 这是我的background-parallax指令的代码:

.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. 您的第一个方法scope.$eval(attr.parallaxActive)是正确的,但是如果将属性值绑定到指令的作用域,则该方法将无效。

Working example: JSFiddle 工作示例: 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. 就是说,我的建议是使用工厂策略将widthWatcher指令转换为服务。 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 工作示例: 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. 为了解决有关在调用parallaxBg链接函数时未定义的值的注释,我更新了JSFiddle以显示调用链接函数的顺序。

In order to understand what is going on, you need to understand how directives are compiled . 为了了解发生了什么,您需要了解如何编译指令

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM