来自服务的初始$广播是在控制器下接收但不在下

时间:2013-11-12 03:42:48

标签: javascript angularjs angularjs-scope

我有一个从<title>标签读取同步数据的指令。然后它触发一个服务$broadcast数据到所有控制器。

但是<body>标记下的控制器没有收到此信息。但是,如果我将ng-app attr从html移至body,并将指令与控制器从head移至body。然后所有控制器都能正常工作。

以下是我的示例代码:http://jsbin.com/oBAMOs/4/edit?html,js,console,output

从代码中我相信你几乎可以猜到我想要做什么。那么为什么会发生这种情况并且有更好的方法来实现这一目标吗?

2 个答案:

答案 0 :(得分:1)

navCtrl在您发送广播时不存在。您可以通过将日志语句放在每个控制器的开头和发送来确认。你会看到你在创建navctrl之前发送。 (“标题”发生然后“发送”然后“导航”)

解决此问题的一种简单方法是在浏览器完成所有当前排队任务(包括渲染其余DOM,从而实现navCtrl的实例化)之后推送$broadcast。您可以通过将广播置于延迟为0的$timeout内来完成此操作。如下所示:

 $timeout (function() {
    $rootScope.$broadcast('processed');
  },0);

并确保在:

中传递超时
.factory('syncPageid', ['$rootScope','$timeout', function($rootScope,$timeout){

这是javascript的单线程特性的副产品。有关为什么超时在这里工作以及潜在问题的讨论,您可以查看:setTimeout with zero delay used often in web pages, why?http://ejohn.org/blog/how-javascript-timers-work/

答案 1 :(得分:0)

而不仅仅是

$rootScope.$broadcast('processed');

你可以

$ rootScope。$ broadcast('processed',“data_you_need_to_pass_around”);

并且像

一样
$scope.$on('processed', function (e, args){
    $scope.title = args;
    console.log('titleCtrl: ' + args);
 });

http://jsbin.com/oBAMOs/11/edit

然后当然你的syncPageid工厂可以将它暴露给对pageid感兴趣的所有其他代码位。但是为了便于在位置之间传递数据而设立工厂并没有多大意义。