在我的AngularJS应用程序中,我有一个管理用户输入的控制器(输入控制器)并广播页面内容控制器的每个重要更改(实际上是内容部分)由几个控制器管理,但让我们保持简单。)
输入控制器提供从数据库中检索的各种元素之间的选择,页面初始化我必须加载输入控制器数据并向内容控制器提供默认选择,以便它可以在页面加载时显示重要数据< /强>
现在我在输入控制器初始化( <script src="https://code.jquery.com/jquery-1.12.0.min.js"></script>
<script>
var mn = $(".main-nav");
mns = "main-nav-scrolled";
hdr = $('header').height();
$(window).scroll(function() {
if( $(this).scrollTop() > hdr ) {
mn.addClass(mns);
} else {
mn.removeClass(mns);
}
});
</script>
.main-nav{
position: relative;
}
.main-nav {
background: #fff;
height: 80px;
z-index: 150;
margin-bottom: -80px;
box-shadow: 0 2px 3px rgba(0, 0, 0, .4);
}
header,.main-nav-scrolled {
position: fixed;
width: 100%;
top: 0;
}
<nav class="main-nav">
<a href="#">Nav Link 1</a>
<a href="#">Nav Link 2</a>
<a href="#">Nav Link 3</a>
<a href="#">Nav Link 4</a>
</nav>
)上拍摄一个事件,但显然角度尚未初始化,因此内容控制器无法捕获事件并且不会渲染实际的内容页面。
我制作了一个JSFiddle来演示行为:
初始化时,第一个控制器正在使用初始数据向第二个控制器发送事件:
$rootScope.$broadcast('inputSelected', inputData);
第二个控制器正在侦听“myEvent&#39;:
”myApp.controller('FirstController', function ($scope, $rootScope) {
$scope.myInput = 'Initial data';
$scope.broadcast = function() {
console.log ('broadcasting: ' + $scope.myInput);
$rootScope.$broadcast('myEvent', $scope.myInput);
};
$scope.broadcast();
});
当页面加载时,第一个事件没有被第二个控制器捕获并且初始数据没有被传递,那么如果你按下按钮 BROADCAST (角度初始化),一切正常。
所以最后一个问题:什么是在初始化时在控制器之间传递数据的最佳方法?有没有办法确保在广播第一个事件之前完全初始化角度?
答案 0 :(得分:3)
包装$ scope.broadcast();在$ scope内调用。$ evalAsync对我有用:
myApp.controller('FirstController', function ($scope, $rootScope) {
$scope.myInput = 'Initial data';
$scope.broadcast = function() {
console.log ('broadcasting: ' + $scope.myInput);
$rootScope.$broadcast('myEvent', $scope.myInput);
};
$scope.$evalAsync( function() {
$scope.broadcast();
});
});
请参阅:https://stackoverflow.com/a/23589271/1288109
请参阅有关$ evalAsync的文档:https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$evalAsync
答案 1 :(得分:0)
基本上听众没有准备好,myEvent已经播出了,所以首先应该将事件发送到控制器“FirstController”,然后广播到“SecondController”然后它就可以了。
这是小提琴
var myApp = angular.module('myApp',[]);
myApp.controller('FirstController', function ($scope, $rootScope) {
$scope.myInput = 'Initial data';
$scope.broadcast = function() {
console.log ('broadcasting: ' + $scope.myInput);
$rootScope.$broadcast('myEvent', $scope.myInput);
};
$rootScope.$on("secondready",function(){
$scope.broadcast();
});
});
myApp.controller('SecondController', function ($scope, $rootScope) {
$scope.$on('myEvent', function (event, args) {
console.log ('myEvent catched - Data: ' + args);
$scope.data = args;
});
$scope.$emit("secondready");
});
https://jsfiddle.net/rbdf6xea/
或者您也可以通过setTimeout来完成