天道酬勤,学无止境

AngularJS $rootScope.$broadcast 在 app.run 中不起作用(AngularJS $rootScope.$broadcast not working in app.run)

问题

我的 AngularJS .run 下有以下代码,它在我的本地开发机器上完美运行,但在上传到我的客户端服务器时不起作用......经过几次测试后,很明显,当控制器加载时,事件不是已触发,因此控制器中取决于此事件的大多数功能不起作用。 有人可以告诉我我在这里做错了什么以及如何解决吗? 谢谢

myApp.run(['AuthDataSvc', '$rootScope', function (AuthDataSvc, $rootScope) {    
    AuthDataSvc.getAuth().then(function(Token){
        $rootScope.$broadcast('Token', Token);
    }, function(status){
        console.log(status);
    });     
}]);
回答1

你总是会遇到竞争条件。 我有几个你可以做的选择:

1) 使用服务。 我不是很喜欢这个选项,因为它会导致意大利面代码。 大多数情况下,您不希望控制器在您登录之前运行。 我更喜欢选项2。

 myApp.run(['AuthDataSvc', '$rootScope', function (AuthDataSvc, $rootScope) {    
    AuthDataSvc.getAuth(); /* no op we will use the service to determine logged in */
}]);


/* inside a controller */
if(AuthDataSvc.isLoggedIn()){
      //do something.
}

2)使用route.resolve。 解析是在路由上定义的,控制器只会在承诺被设置为解析后才加载。 我向你展示了一个ui-routerng-route的例子,你需要选择你的毒药。 如果你不使用 ui-router 你应该考虑它。

/* app.config ... route config.. */
var waitForLogon = {
      UserToken: ["AuthDataSvc", function (AuthDataSvc) {
         return AuthDataSvc.logon();
      }]
};

//this is for ng-route
 $routeProvider
   .when('/Book/:bookId', {
      templateUrl: '--',
      controller: 'MyCtrl',
      resolve: waitForLogon
   })


//this is for ui-router 
$stateProvider
     .state('me', {
            templateUrl: '--',
            controller: 'MeCtrl',
            resolve: waitForLogon
 })

/* controller */
 angular.module('yourapp')
    .controller('MyCtrl', ["UserToken", ... , function(UserToken){
                  //User Token will always be here when your Ctrl loads.
   });

/* service code -- */
angular.module('yourapp')
    .service('AuthDataSvc', ["LogonModel", "$q", function(LogonModel, $q) {
        this._q = null;
        var that = this;
        this._doAuth = function(){
           this.getAuth().then(function(Token){ that._q.resolve(Token) }, function(error){that._q.reject(error);}
        };
        this.logon = function () {
            if(!this._q){
              this._q = $q.defer();
               this._doAuth();// <-current auth do here, and resolve this._q when done
            }
            return this._q.promise;
        };
    });
标签

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • 如何在 Angularjs 中观察按键组合? [复制](How to watch for a keypress combination in Angularjs? [duplicate])
    问题 这个问题在这里已经有了答案: AngularJS - 同时按下多个按键(4 个回答) 2年前关闭。 我正在尝试让我的控制器观察按键组合。 为了论证起见,让我们说: up up down down left right left right b a。 无论用户当前在页面中的哪个位置,我如何才能有角度地注意这些? 回答1 看起来您可以使用 ng-keydown 来执行此操作。 这是一个工作的plunker。 对于这个示例,我只是将ng-keydown绑定到<body> 。 在全局范围内捕获所有键盘事件非常有效。 正如@charlietfl 指出的那样, ng-keydown注册了很多键盘事件,因此要使其可用需要大量工作。 例如,如果您尝试侦听组合(如ctrl + r ),则ctrl键将注册多次。 JS: var myApp = angular.module('myApp', []); myApp.controller('Ctrl', function($scope) { $scope.keyBuffer = []; function arrays_equal(a,b) { return !(a<b || b<a); } $scope.down = function(e) { $scope.keyBuffer.push(e.keyCode); var upUp = [38, 38
  • AngularJS / ui-router:$state.go 在 ng-click 中不起作用(AngularJS / ui-router: $state.go does not work inside ng-click)
    问题 我有一个视图,其中包含以下代码: <input type="button" value="New Post" ng-click="$state.go('blog.new-post')"> 目标是在不必使用 href 的情况下转换到新状态。 不幸的是,上面的代码没有触发。 我还尝试在此视图的控制器中包含 $state: app.controller('blogPostsController', function($scope, $stateParams, $http, $state) ... 但还是什么都没有。 transictionTo 似乎也不起作用。 任何人都知道如何使这项工作? 编辑:我只能通过分配使其工作: $scope.$state = $state; 在我的控制器里面。 这看起来很丑。 真的没有其他方法可以访问 $state 而不将其分配给作用域吗? 回答1 根据 https://github.com/angular-ui/ui-router/wiki/Quick-Reference#note-about-using-state-within-a-template 您可以将其添加到$rootScope ,因此它将可用在所有范围内,因此在所有模板中,通过 angular.module("myApp").run(function ($rootScope, $state
  • 为什么我们在AngularJS中使用$ rootScope。$ broadcast?(Why do we use $rootScope.$broadcast in AngularJS?)
    问题 试图找到AngularJS $rootScope.$broadcast一些基本信息,但是AngularJS文档并没有太大帮助。 简单地说,我们为什么要使用它? 另外,在John Papa的Hot Towel模板中,在名为$broadcast的通用模块中有一个自定义函数: function $broadcast() { return $rootScope.$broadcast.apply($rootScope, arguments); } 我不明白这是怎么回事。 因此,这是几个基本问​​题: 1) $rootScope.$broadcast什么作用? 2) $rootScope.$broadcast和$rootScope.$broadcast.apply什么区别? 回答1 $rootScope.$broadcast什么作用? $rootScope.$broadcast通过应用程序范围发送事件。 该应用程序的任何子级范围都可以使用以下简单方法来捕获它: $scope.$on() 。 当您想要到达不是直接父级的范围(例如,父级的分支)时,发送事件特别有用 !!! 但是,要做的一件事是从控制器使用$rootScope.$on 。 $rootScope是应用程序,当您的控制器被销毁时,该事件侦听器将仍然存在,并且当再次创建您的控制器时,它将堆积更多的事件侦听器。 (因此
  • 在AngularJS中的视图之间切换时保持范围模型(Maintain model of scope when changing between views in AngularJS)
    问题 我正在学习AngularJS。 比方说,I /厂景使用My1Ctrl,和/视图2使用My2Ctrl有; 可以使用选项卡导航到该选项卡,其中每个视图都有其自己的简单但不同的形式。 当用户离开然后返回到view1时,如何确保未重置以view1形式输入的值? 我的意思是,第二次访问view1如何保持与我离开模型时完全相同的状态? 回答1 我花了一些时间来确定什么是最好的方法。 我还想保留状态,即当用户离开页面然后按返回按钮返回到旧页面时; 而不仅仅是将我所有的数据都放到rootscope中。 最终结果是为每个控制器提供服务。 在控制器中,只有清除的函数和变量才不需要。 控制器的服务是通过依赖项注入来注入的。 由于服务是单例的,因此它们的数据不会像控制器中的数据那样被破坏。 在服务中,我有一个模型。 该模型仅具有数据-无功能-。 这样,就可以从JSON来回转换它以持久化它。 我使用html5 localstorage进行持久化。 最后,我使用window.onbeforeunload和$rootScope.$broadcast('saveState'); 让所有服务知道应该保存其状态,并让$rootScope.$broadcast('restoreState')让他们知道恢复其状态(用于当用户离开页面并按返回按钮以返回到页面)。
  • AngularJs广播重复执行太多次(AngularJs broadcast repeating execution too many times)
    问题 在我的一个Angular控制器中,我有以下内容: // controller A $rootScope.$on("myEventFire", function(event, reload) { someAction(); }); 在另一个控制器中,我有这个: // controller B $scope.openList = function(page) { $rootScope.$broadcast('myEventFire', 1); } 现在,这是一个单页应用程序。 当我最初进入控制器A并尝试触发此事件时, someAction()将被执行一次。 如果我离开并再次返回到控制器A并执行相同的操作,则someAction()将执行两次。 如果我再次执行此操作,则会发生3次,依此类推。 我在这里做错了什么? 回答1 您可以尝试只使用$scope.$on()吗? 每次创建控制器A时,它都会在根作用域上添加一个新的侦听器,并且当您前后导航时,该侦听器不会被销毁。 如果在控制器的本地范围内执行此操作,则当您离开时,侦听器应被删除,并且范围被破坏。 // controller A $scope.$on("myEventFire", function(event, reload) { someAction(); }); $broadcast将事件向下发送到所有子作用域
  • AngularJS完成加载后发送事件(Sending event when AngularJS finished loading)
    问题 想知道当所有指令都完成编译/链接时,检测页面加载/引导完成的最佳方法是什么。 已经有活动了吗? 我应该重载引导程序功能吗? 回答1 只是预感:为什么不看看ngCloak指令是如何执行的呢? 显然,ngCloak伪指令设法在内容加载后显示内容。 我敢打赌ngCloak会导致确切的答案... 1小时后编辑:好的,我看了ngCloak,它真的很短。 显然,这意味着编译函数只有在评估了{{template}}表达式(即,它加载的模板)后才会执行,因此ngCloak指令具有很好的功能。 我的有根据的猜测是只是使用ngCloak一样简单的方式创建一条指令,然后在您的编译函数中执行您想做的任何事情。 :)将指令放置在应用程序的根元素上。 您可以像myOnload这样调用该指令,并将其用作my-onload属性。 模板编译完成(评估表达式并加载子模板)后,将执行compile函数。 23小时后,编辑:好的,所以我做了一些研究,我也问了自己的问题。 我提出的问题与该问题间接相关,但它恰巧使我找到了解决该问题的答案。 答案是,您可以创建一个简单的指令,然后将代码放入该指令的链接函数中,该链接函数(在大多数情况下,将在下面说明)将在元素准备就绪/加载时运行。 根据Josh对编译和链接函数执行顺序的描述, 如果您有此标记: <div directive1> <div directive2> <!--
  • AngularJS:在指令中绑定到全局事件的最佳方法是什么(AngularJS : What is the best way to bind to a global event in a directive)
    问题 想象一下在 AngularJS 中你想要创建一个需要响应全局事件的指令的情况。 在这种情况下,假设是窗口调整大小事件。 最好的方法是什么? 在我看来,我们有两个选择: 1. 让每个指令绑定到事件并在当前元素上执行魔术 2. 创建一个全局事件侦听器,它执行 DOM 选择器以获取逻辑应该在的每个元素应用。 选项 1 的优点是您已经可以访问要对其执行某些操作的元素。 但是...选项 2 的优点是您不必在同一事件上多次绑定(对于每个指令),这可以提高性能。 让我们来说明这两个选项: 选项1: angular.module('app').directive('myDirective', function(){ function doSomethingFancy(el){ // In here we have our operations on the element } return { link: function(scope, element){ // Bind to the window resize event for each directive instance. angular.element(window).on('resize', function(){ doSomethingFancy(element); }); } }; }); 选项 2: angular
  • AngularJs-取消路线更改事件(AngularJs - cancel route change event)
    问题 如何在AngularJs中取消路线更改事件? 我当前的代码是 $rootScope.$on("$routeChangeStart", function (event, next, current) { // do some validation checks if(validation checks fails){ console.log("validation failed"); window.history.back(); // Cancel Route Change and stay on current page } }); 即使验证失败,Angular也会提取下一个模板和关联的数据,然后立即切换回上一个视图/路线。 如果验证失败,我不希望angular提取下一个模板和数据,理想情况下应该没有window.history.back()。 我什至尝试过event.preventDefault()但没有用。 回答1 代替$routeChangeStart使用$locationChangeStart 这是来自angularjs家伙的讨论:https://github.com/angular/angular.js/issues/2109 编辑3/6/2018您可以在文档中找到它:https: //docs.angularjs.org/api/ng/service/
  • AngularJS $rootScope.$broadcast not working in app.run
    I have the following code under my AngularJS .run which works perfectly on my local development machine but won't work when uploaded to my client server...after few tests it is obvious that by the time the controller is loaded the event is not triggered yet so most of the functions in the controller depending on this event do not work. Can someone please tell me what I am doing wrong here and how to fix it? Thanks myApp.run(['AuthDataSvc', '$rootScope', function (AuthDataSvc, $rootScope) { AuthDataSvc.getAuth().then(function(Token){ $rootScope.$broadcast('Token', Token); }, function(status){
  • 在 Angularjs 模块的“run”方法中注入依赖(Inject dependencies in “run” method of the module in Angularjs)
    问题 我试图了解我如何使用 Angularjs。 它看起来像一个不错的框架,但我在 DI 方面遇到了一个小问题...... 如何在模块的“运行”方法中注入依赖项? 我的意思是我能够做到,但只有当我的服务/工厂/值与“运行”参数名称同名时才有效。 我构建了一个简单的应用程序来说明我的意思: var CONFIGURATION = "Configuration"; //I would like to have App.Configuration var LOG_SERVICE = "LogService"; //I would like to have App.Services.LogService var LOGIN_CONTROLLER = "LoginController"; var App = {}; App.Services = {}; App.Controllers = {}; App = angular.extend(App, angular.module("App", []) .run(function ($rootScope, $location, Configuration, LogService) { //How to force LogService to be the logger in params? //not var = logger =
  • ng-submit 在 angularjs 中不起作用(ng-submit not working in angularjs)
    问题 我的看法: <div class="modal" tabindex="-1" role="dialog" ng-controller="LocationController"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" ng-click="$hide()">×</button> <h4 class="modal-title"> Add a Location </h4> </div> <div class="modal-body"> <form class="form-horizontal" role="form" ng-submit="createLocation()"> <div class="form-group"> <label class="col-sm-2 control-label">Name</label> <div class="col-sm-10"> <input type="text" class="form-control" placeholder="Warehouse A, Row 15, Shelf BC1, etc" ng-model="name"> <
  • 在AngularJS中的控制器之间进行通信的正确方法是什么?(What's the correct way to communicate between controllers in AngularJS?)
    问题 控制器之间进行通讯的正确方法是什么? 我目前正在使用一个涉及window的可怕软糖: function StockSubgroupCtrl($scope, $http) { $scope.subgroups = []; $scope.handleSubgroupsLoaded = function(data, status) { $scope.subgroups = data; } $scope.fetch = function(prod_grp) { $http.get('/api/stock/groups/' + prod_grp + '/subgroups/').success($scope.handleSubgroupsLoaded); } window.fetchStockSubgroups = $scope.fetch; } function StockGroupCtrl($scope, $http) { ... $scope.select = function(prod_grp) { $scope.selectedGroup = prod_grp; window.fetchStockSubgroups(prod_grp); } } 回答1 编辑:此答案中解决的问题已在angular.js版本1.2.7中解决。 现在,
  • 如何检测用户是否单击了Angularjs中的浏览器后退按钮(How to detect if a user clicks browser back button in Angularjs)
    问题 我有一个带有一些数据的类似表单的页面。 并希望在用户单击浏览器后退按钮时显示弹出窗口/警告,询问“他们是否要返回或停留在同一页面上”。 我正在使用angular-ui-router的$stateProvider并且只想将此绑定到一个状态/视图。 回答1 这是我之前对其他问题的回答,但对您有所帮助 您可以使用angular $routeChangeStart来完成此$routeChangeStart $ routeChangeStart 在更改路线之前广播。 此时,路由服务开始解决发生路由更改所需的所有依赖关系。 通常,这涉及获取视图模板以及在resolve route属性中定义的所有依赖项。 解决所有依赖性后,将触发$ routeChangeSuccess。 可以通过调用事件的preventDefault方法来防止路由更改(以及触发它的$location更改)。 有关事件对象的更多详细信息,请参见$rootScope.Scope 。 因此,请尝试以下代码。 $scope.$on('$routeChangeStart', function (scope, next, current) { if (next.$$route.controller != "Your Controller Name") { // Show here for your model, and do
  • 指令之间的AngularJS通信(AngularJS communication between directives)
    问题 我是Angular.js的新手,我的应用程序需要指令之间的某些通信,我阅读了一些有关链接和要求的文档,但无法确切了解其工作原理。 对于一个简单的例子,我有:live小提琴:http://jsfiddle.net/yw235n98/5/ 2个指令:firstDir,secondDir ::带有一些数据 firstDir具有单击功能,它将更改数据值当firsDir单击功能被触发时,我也想在secondDir中更改数据。 HTML: <body ng-app="myApp"> First Directive : <first-dir > <h3>{{firstCtrl.data}}</h3> <button ng-click="firstCtrl.set('NEW VALUE')">Change Value</button> </first-dir> Second Directive : <second-dir> <h3>{{secondCtrl.data}}</h3> </second-dir> Javascript: (function(){ var app = angular.module('myApp', []); app.directive("firstDir", function(){ return { restrict : 'E', controller
  • 改进此AngularJS工厂以与socket.io一起使用(Improve this AngularJS factory to use with socket.io)
    问题 我想在AngularJS中使用socket.io。 我找到了以下工厂: app.factory('socket', function ($rootScope) { var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, function () { var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); }, emit: function (eventName, data, callback) { socket.emit(eventName, data, function () { var args = arguments; $rootScope.$apply(function () { if (callback) { callback.apply(socket, args); } }); }) } }; 它在控制器中的使用方式如下: function MyCtrl($scope, socket) { socket.on('message', function(data) { ... }); }; 问题在于
  • 一个AngularJS控制器可以调用另一个吗?(Can one AngularJS controller call another?)
    问题 一个控制器可以使用另一个控制器吗? 例如: 该HTML文档仅在messageCtrl.js文件中打印由MessageCtrl控制器传递的MessageCtrl 。 <html xmlns:ng="http://angularjs.org/"> <head> <meta charset="utf-8" /> <title>Inter Controller Communication</title> </head> <body> <div ng:controller="MessageCtrl"> <p>{{message}}</p> </div> <!-- Angular Scripts --> <script src="http://code.angularjs.org/angular-0.9.19.js" ng:autobind></script> <script src="js/messageCtrl.js" type="text/javascript"></script> </body> </html> 控制器文件包含以下代码: function MessageCtrl() { this.message = function() { return "The current date is: " + new Date().toString(); }; } 它只是打印当前日期
  • AngularJS:绑定到服务属性的正确方法(AngularJS : The correct way of binding to a service properties)
    问题 我正在寻找有关如何绑定到AngularJS中的服务属性的最佳实践。 我已经研究了多个示例,以了解如何绑定到使用AngularJS创建的服务中的属性。 下面有两个关于如何绑定到服务中的属性的示例。 他们都工作。 第一个示例使用基本绑定,第二个示例使用$ scope。$ watch绑定到服务属性 绑定到服务中的属性时,这些示例是首选还是建议使用其他我不知道的选项? 这些示例的前提是服务应每5秒更新其属性“ lastUpdated”和“ calls”。 服务属性更新后,视图应反映这些更改。 这两个示例均成功运行; 我想知道是否有更好的方法。 基本绑定 可以在下面的代码中查看和运行以下代码:http://plnkr.co/edit/d3c16z <html> <body ng-app="ServiceNotification" > <div ng-controller="TimerCtrl1" style="border-style:dotted"> TimerCtrl1 <br/> Last Updated: {{timerData.lastUpdated}}<br/> Last Updated: {{timerData.calls}}<br/> </div> <script src="https://ajax.googleapis.com/ajax/libs/angularjs
  • AngularJS中的循环依赖和OOP问题(Problems with circular dependency and OOP in AngularJS)
    问题 AngularJS + OOP是一种使用起来很性感的功能 嗨,我已经成功将AngularJs与OOP结合使用了一段时间(首先是从使用oop继承的angularjs开始),所提供的方法允许您将类定义为角度服务,以后可以像这样扩展或继承: Application.factory('AbstractObject', [function () { var AbstractObject = Class.extend({ virtualMethod: function() { alert("Hello world"); }, abstractMethod: function() { // You may omit abstract definitions, but they make your interface more readable throw new Error("Pure abstract call"); } }); return AbstractObject; // You return class definition instead of it's instance }]); Application.factory('DerivedObject', ['AbstractObject', function (AbstractObject) { var
  • AngularJS中$ broadcast(),$ emit()和$ on()的用法(Usage of $broadcast(), $emit() And $on() in AngularJS)
    问题 我知道$Broadcast() , $Emit()和$On()用于引发一个控制器中的事件并在另一个控制器中进行处理。 如果可能的话,有人可以给我一些有关上述三种用法的实时示例,因为我是angular JS新手吗? 我通过以下链接了解了基本用法。 http://www.binaryintellect.net/articles/5d8be0b6-e294-457e-82b0-ba7cc10cae0e.aspx 回答1 $ emit 它通过范围层次结构向上调度事件名称,并通知已注册的$rootScope.Scope侦听器。 事件生命周期从调用$emit的范围开始。 事件向上遍历到根作用域,并在此过程中调用所有已注册的侦听器。 如果其中一个侦听器取消了该事件,则该事件将停止传播。 $广播 它将事件名称向下分配给所有子作用域(及其子作用域),并通知已注册的$rootScope.Scope侦听器。 事件生命周期始于调用$broadcast的范围。 该范围内事件的所有侦听器都将得到通知。 之后,事件向下遍历子作用域,并沿途调用所有已注册的侦听器。 该事件无法取消。 $ on 它侦听给定类型的事件。 它可以捕获$broadcast和$emit调度的事件。 视觉演示: 演示工作代码,以可视方式显示范围树(父/子关系): http://plnkr.co/edit/am6IDw?p=preview
  • AngularJS 如何在登录后重定向回下一个路由(AngularJS How to redirect back to the next route after logging in)
    问题 使用 $rootScope.$on('$routeChangeStart', function(event, next, current),如果路由需要身份验证,我将重定向到登录页面。这非常有效。 登录后如何重定向回预期路线? 回答1 这是对我有用的简化版本: app = angular.module('ngApp', []).config(function ($routeProvider) { $routeProvider .when('/dashboard', { templateUrl: 'dashboard.html', controller: 'dashboardController', loginRequired: true // }) .when('/login', { templateUrl: 'login.html', controller: 'loginController' }) .otherwise({redirectTo: '/login'}) }); 然后在应用程序的运行块中: app.run(function ($location, $rootScope) { var postLogInRoute; $rootScope.$on('$routeChangeStart', function (event, nextRoute