angular系列彻底的异步解决
Angular 的异步处理的真的很不错。基于消息⼴播的⽅式,并且可以向上传递,基本上解决了不同模块,不同controller之间不⽅便异步的问题。
场景⼀:通过回调函数进⾏异步操作(该情况下不⽤消息⼴播的机制)
这种情况的特点是直接传递⼀个回调函数给异步操作就可以了,等异步操作完执⾏回调。
⽐如:controller通过server异步取数据,等取完数据进⾏⼀系列的操作,这个时候就可以把操作封装到函数中,传递给异步操作函数。        controller代码⽚段举例如下:
[javascript]
1. $scope.submit=function(){
2.    userService.login($scope.user.loginname.value,$scope.user.password.value,function(data){
3.        if(data.success){
4.            location.href = '../../views/main/index.html';
5.        }else{
6.            $tip=data.msg;
7.        }
8.    });
9. };
最后⼀个参数即为回调函数
server代码⽚段举例如下:
[javascript]
1. return {
2.        http:$http,
3.    token:'',
4.    auth:[],
5.    loginname:'',
6.    login:function(loginname,password,fn){
7.          this.http({
8.        url:'../../scripts/loginModule/services/loginOKTest.js',
9.        method:'GET'
10.          })
11.          .success(function(data){
12.          if(data[0].success){
13.              ...
14.                      //调⽤回调⽅法
15.                      fn(data[0]);
16.          }
17.            })
18.          .error(function(data,header,config,status){
19.        alert("验证服务请求失败!");
20.          });
21.    }
22. }
场景⼆:没有传递回调函数的地⽅,这个时候就必须⽤到消息⼴播的机制。
⽐如:我的controller通过server异步获取数据,这个时候我⽤回调函数保证取到数据后做后续操作。但是我的后续操作需要通过指令进⾏DOM的⽣成。这个时候我们是没有办法直接调⽤指令的link或者compile的。这个时候我们需要⽤到⼴播$scope.$broadcast。发送⼴播以后,需要通过$scope.$on进⾏
监听。
controller代码⽚段举例如下:
[javascript]
1. //通过categoryService异步取数据
2. categoryService.initCategory(loginname,token,function(category){
3.        $scope.category=category;
4.        $scope.$broadcast("categoryLoaded");
5. });
service代码⽚段举例如下:
[javascript]
1. initCategory:function(loginname,token,fn){
2.    this.http({
3.    url:'../../scripts/mainModule/services/mainCategory.js',
4.    method:'GET'
5.    }).success(function(data,header,config,status){
6.        fn(data);
7.        }).error(function(data,header,config,status){
8.        alert("验证服务请求失败!");
9.    });
10. }
directive代码⽚段举例如下:
[javascript]
1. link:function ($scope, $elem, attrs) {
2.      $scope.$on("categoryLoaded", function (event, args) {
3.            //$scope.category即为异步获取的数据
4.      }
5. }
最后,如果我们在这个controller中需要调⽤另外⼀个模块的指令的link或者compile或者另⼀个模块的controller怎么办。我们需要通过依赖注⼊$rootScope服务,因为他是所有作⽤域的⽗,然后调⽤$emit这个服务进⾏⼴播。指令中通过$rootScope.$on进⾏接收即可。
模块1(app.video)中的controller代码⽚段举例如下:
[javascript]
1. $play=function(id){
2.    console.log("click replay id:"+id);
3.    clearReply();
4.    //通过$rootScope⼴播消息给app.dialog模块的controller
5.    $rootScope.$emit("openTemplate","reply.html");
6. };
模块2(app.dialog)中的controller代码⽚段举例如下:
[javascript]
1. $rootScope.$on('openTemplate',function(event, toState, toParams, fromState, fromParams){
2.        $scope.openTemplate(toState);
3. });
4.
5. $scope.openTemplate = function (url) {
6.        if(!url)
again yui7.            url="/ZVideo-MVC/dialog/defaultTemplate.html";
8.        $scope.value = true;
9.        ngDialog.open({
10.            template: url,
11.            className: 'ngdialog-theme-plain',
12.            scope: $scope
13.        });
14. };