隐藏/显示经过身份验证的用户的元素的指令

时间:2014-11-30 11:47:09

标签: javascript angularjs

在自定义指令处理程序中隐藏/显示元素的正确方法是什么?

在我的应用程序中,我有许多元素应该根据用户身份验证状态隐藏/显示。要跟踪我创建'Auth'服务的状态。目前我担心“Auth”服务几乎注入每个控制器。为了避免这种情况,我决定创建一个基于'Auth'服务状态显示/隐藏元素的指令会更好。像

这样的东西
<div data-app-auth-only="true">Content is visible only for authenticated users</div>

我已阅读角度指令教程,创建指令并在Auth服务上设置监视。每当Auth状态发生变化时,我都会触发处理程序,但我仍然坚持隐藏/显示元素。在一些教程中,我看到人们使用'element.hide()'命令,但由于某些原因,我的情况下没有定义hide()。

以我的例子为the link to Plunkr

我也担心指令是否正确。这类任务的最佳实践是什么?是否值得制定指令或者将“Auth”注入根范围会更好?

2 个答案:

答案 0 :(得分:2)

解决方案

在这些教程中,hide()show()最有可能来自jQuery。要使用这些方法,您需要在添加AngularJS之前添加jQuery。然后,更改您的指令,例如:

app.directive('appAuthOnly', ['Auth', function(Auth) {
  function link(scope, element, attrs) {
    scope.$watch(Auth.isAuth, function(value, oldValue) {
      if (Auth.isAuth()) {
        element.show();
      } else {
        element.hide();
      }
    });
  }

  return {
    link: link
  };
}]);

如果您不想为jQuery添加依赖项,则可以使用element.addClass("my-class-name")element.removeClass("my-class-name")。这两种方法包含在AngularJS (jqLite)中。在这种情况下,my-class-name是一个将显示设置为无(display: none)的CSS类。

您可以查看my forked plunker的解决方案。我试图尽可能少地更改你的代码。

编辑

在我的项目中,我在这个场景中使用了一个指令。我发现它们简单而灵活。如果您最终需要权限,则可以将参数传递给指令以检查Auth工厂的给定权限。 (app-auth-only="my-permission")此时,我还将我的指令重命名为required-permissions="view:this, view:that

在我看来,这些指令作为评论,阶级或元素并不合理。所以我也只限制它的属性。

app.directive('appAuthOnly', ['Auth', function(Auth) {
  return {
    restrict: 'A',  // Forces the directive to be an attribute.
    link: function link(scope, element, attrs) {
      scope.$watch(Auth.isAuth, function(value, oldValue) {
        if (Auth.isAuth()) {
          element.show();
        } else {
          element.hide();
        }
      });
    }
  };
}]);

在这两个例子中,我都使用jQuery来简化。在一个真实的项目中,我不想为此包含jQuery。我会实施addClassremoveClass解决方案。我发现包含jQuery让我很容易回到我糟糕的jQuery habbits。

答案 1 :(得分:0)

我所做的是将服务,您的案例中的AuthService注入每个相关的控制器,并放在HTML元素上:

<div ng-show="showAuthContent()">Create Ticket</div>

在控制器中我将在范围上有一个功能:

$scope.showAuthContent = function() {
      // call to logic, preferably in a auth service so it can be reused
      // and also no business logic in controller
}