AngularJS:以编程方式将ngIf添加到指令的最佳做法是什么? [英] AngularJS: What's the best practice to add ngIf to a directive programmatically?

查看:140
本文介绍了AngularJS:以编程方式将ngIf添加到指令的最佳做法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个指令,根据来自服务的值检查dom中是否存在元素(例如,检查用户角色)。

I want to create a directive that checks if an element should be present in the dom based on a value coming from a service (e.g. check for a user role).

相应的指令如下所示:

angular.module('app', []).directive('addCondition', function($rootScope) {
    return {
        restrict: 'A',
        compile: function (element, attr) {
          var ngIf = attr.ngIf,
              value = $rootScope.$eval(attr.addCondition);

          /**
           * Make sure to combine with existing ngIf!
           * I want to modify the expression to be evalued by ngIf here based on a role 
           * check for example
           */
          if (ngIf) {
            value += ' && ' + ngIf;
          }

          attr.$set('ng-if', value);
        }
    };
});

最后元素附加了ng-if属性但不知何故它不适用于元素,它仍然存在于dom中。所以这显然是一种错误的做法。

At the end the element has the ng-if attribute attached but somehow it doesn't apply to the element and it is still existing in the dom. So this is obviously a wrong approach.

这个小提琴显示了这个问题: http://jsfiddle.net/L37tZ/ 2 /

This fiddle shows the problem: http://jsfiddle.net/L37tZ/2/

谁能解释为什么会这样?有没有其他方式可以实现类似的行为?应考虑现有的ngIfs。

Who can explain why this happens? Is there any other way a similar behaviour could be achieved? Existing ngIfs should be considered.

用法:< div rln -require-roles =['ADMIN','USER']>当这些角色要求不满意时我隐藏了!< / div>

.directive('rlnRequireRoles', function ($animate, Session) {

  return {
    transclude: 'element',
    priority: 600,
    terminal: true,
    restrict: 'A',
    link: function ($scope, $element, $attr, ctrl, $transclude) {
      var block, childScope, roles;

      $attr.$observe('rlnRequireRoles', function (value) {
        roles = $scope.$eval(value);
        if (Session.hasRoles(roles)) {
          if (!childScope) {
            childScope = $scope.$new();
            $transclude(childScope, function (clone) {
              block = {
                startNode: clone[0],
                endNode: clone[clone.length++] = document.createComment(' end rlnRequireRoles: ' + $attr.rlnRequireRoles + ' ')
              };
              $animate.enter(clone, $element.parent(), $element);
            });
          }
        } else {

          if (childScope) {
            childScope.$destroy();
            childScope = null;
          }

          if (block) {
            $animate.leave(getBlockElements(block));
            block = null;
          }
        }
      });
    }
  };
});

在指令中添加优先级非常重要,否则附加到该元素的其他指令不是评估!

It is very important to add the priority in the directive, otherwise other directives attached to that element are not evaluated!

推荐答案

问题的第一部分为什么?是我能回答的问题:

The first part of your question, "why?", is something I can answer:

您遇到的问题是,如果不在元素上调用 $ compile ,则无法动态地将指令应用于元素。

The problem you are running into is that you can't dynamically apply directives to elements without calling $compile on the element.

如果在设置属性后调用 $ compile(element)(element.scope()),则会遇到堆栈溢出,因为你正在编译自己,导致你自己编译,导致你自己编译,等等。

If you call $compile(element)(element.scope()) after you set the attribute, you run into a stack overflow because you are compiling yourself, which cause you to compile yourself which causes you to compile yourself, etc.

第二部分,如何实现,我遇到了麻烦。我尝试了几种方法(比如使用嵌套的 ng-if 来转换内容),但我无法准确地获得您正在寻找的行为。

The second part, "how else to achieve", I am having trouble with. I tried a couple of approaches (like transcluding the content with a nested ng-if) but I can't get exactly the behavior you are looking for.

我认为下一步可能是研究 ng-if 并尝试直接在您的指令中实现类似的东西。

I think the next step might be to study the code for ng-if and try to implement something similar directly in your directive.

这是一个让它工作的第一步。我希望它需要一些清理和修改才能让它按照你真正想要的方式工作。

Here is a first pass of getting it working. I expect it needs some cleanup and modification to get it working how you really want it, however.

这篇关于AngularJS:以编程方式将ngIf添加到指令的最佳做法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆