【问题标题】:Using $emit method correctly to show modal正确使用 $emit 方法来显示模态
【发布时间】:2014-02-26 00:22:39
【问题描述】:

我想知道如何正确使用$emit 方法,以便在我的错误回调中触发一个模态。

我有以下工厂:

angular.module('BBPlnkr').factory("Session", [
  '$http', '$q', '$rootScope', function($http, $q, $rootScope) {
    var service;
    service = {
      requestCurrentUser: function() {
        if (service.isAuthenticated()) {
          return $q.when(service.currentUser);
        } else {

        }
        return $http.get('current_user').then(function(resp) {
          console.log(resp.data);
          service.currentUser = resp.data;
          return service.currentUser;
        }, function(resp) {
          if (resp.status === 401) {
            $rootScope.$emit("loginRequired", "err");
            console.log('You are not authetnicated');
          }
        });
      },
      currentUser: null,
      isAuthenticated: function() {
        return !!service.currentUser;
      }
    };
    return service;
  }
]);

这个工厂所做的只是检查用户是否是 current_user,如果不是,则返回 401。我想做的是在错误回调中当调用此错误回调时触发一个模式。现在我发现我可以使用$emit 方法,但不确定我是否正确使用它。在错误回调中,我想通过作用域链向上调度事件。这就是$emit 做对的事情。但我不完全确定我是否正确设置。所以在这样做。我的控制器是这样的:

myApp.controller('MainController', ['$scope', '$rootScope', '$modal', '$location', '$route', function($scope, $rootScope, $modal, $location, $route) {

      $rootScope.$on('loginRequired', function(event, second_param){
        /* Do the modal stuff here??*/
    });
  }
]);

我知道我实际上并没有做任何事情来触发模式 ($modal.open)。但我想知道我是否朝着正确的方向前进。如果没有,一些建议会有所帮助。我在网上查找了有关$emit$broadcast 的文档。我知道两者的区别。一次在作用域链上分派事件,一个在 $scope 链下分派事件。

【问题讨论】:

  • $rootScope 在顶部,所以要使用 $broadcast 发送。

标签: javascript angularjs


【解决方案1】:

选项 1

angular.module('BBPlnkr').factory("Session", [
  '$http', '$q', '$rootScope','$scope', function($http, $q, $rootScope,$scope) {
    var service;
    service = {
      requestCurrentUser: function() {
        if (service.isAuthenticated()) {
          return $q.when(service.currentUser);
        } else {

        }
        return $http.get('current_user').then(function(resp) {
          console.log(resp.data);
          service.currentUser = resp.data;
          return service.currentUser;
        }, function(resp) {
          if (resp.status === 401) {
            $scope.$emit("loginRequired", "err");
            console.log('You are not authetnicated');
          }
        });
      },
      currentUser: null,
      isAuthenticated: function() {
        return !!service.currentUser;
      }
    };
    return service;
  }
]);

选项2

myApp.controller('MainController', ['$scope', '$rootScope', '$modal', '$location', '$route', function($scope, $rootScope, $modal, $location, $route) {
$rootScope.loginRequired = fn(){}

  }
]);

angular.module('BBPlnkr').factory("Session", [
  '$http', '$q', '$rootScope', function($http, $q, $rootScope) {
    var service;
    service = {
      requestCurrentUser: function() {
        if (service.isAuthenticated()) {
          return $q.when(service.currentUser);
        } else {

        }
        return $http.get('current_user').then(function(resp) {
          console.log(resp.data);
          service.currentUser = resp.data;
          return service.currentUser;
        }, function(resp) {
          if (resp.status === 401) {
            $rootScope.loginRequired()
            console.log('You are not authetnicated');
          }
        });
      },
      currentUser: null,
      isAuthenticated: function() {
        return !!service.currentUser;
      }
    };
    return service;
  }
]);

但我认为你过度使用根范围以及发射和广播的范围

  1. Emit 和 Broadcast 用于跨范围通信,这里您使用的是在同一范围内进行通信。 $rootScope 仅适用于整个应用程序。它是一种全局缓存。
  2. 由于 rootScope 是全局的并且跨应用程序是唯一的,因此您应该谨慎使用它。我会选择选项 1,因为只有顶层模块正在访问 rootScope,它也只是为了监听子作用域在做什么。

参考:http://docs.angularjs.org/api/ng/type/$rootScope.Scope

【讨论】:

  • 感谢您的详细解释。但是...使用选项 1。我确定您无法在工厂级别访问 $scope。此外,查看:stackoverflow.com/a/19498009/3189939 他建议:使用 $rootScope.$emit+ $rootScope.$on 还使用 $emit 通过通知注册的范围层次结构向上调度事件名称。那么使用$emit而不是$broadcast不是明智之举
  • 使用$broadcast 的初步建议有效。在我的控制器中,我执行$scope.on('loginRequired, function(){ console.log 'something happened });,它可以工作
【解决方案2】:

Himangshuj mentions some good points 关于上面的范围,所以我不会插话。

如果您正在寻找一种从控制器中处理对话框的简洁方式,该线程有一个指令,可用于 Bootstrap 或类似的模态对话框框架。

Simple Angular Directive for Bootstrap Modal

使用指令和对话框标记,在控制器中显示模式应该像$scope.showDialog = true; 一样简单。

希望对您有所帮助。

【讨论】:

    猜你喜欢
    • 2011-02-10
    • 1970-01-01
    • 1970-01-01
    • 2016-04-06
    • 2019-07-27
    • 2016-07-25
    • 2015-01-16
    • 2017-09-25
    相关资源
    最近更新 更多