在多个控制器中使用AngularJs Service

时间:2016-04-06 07:55:48

标签: javascript angularjs

我在这里挣扎着角。我学到的是模块的工厂和服务功能只创建一个对象的一个​​实例,它将属性(函数和变量)与它相关联。并且该实例可在整个应用程序的控制器中使用。

在我的应用中,我创建了一个服务模块userAngService,如下所示:

var ser = angular.module('userAngService',[]);

ser.service('userAngService',['$cookies','$location','$http','$log','$rootScope',function($cookies,$location,$http,$log,$rootScope){
    this.user = {};
    $rootScope.username = {};
    $rootScope.user = {};

    /*this.loadUserData = function(username){
        return $http({
            method: 'GET',
            url: 'http://localhost:7070/storyBoard/webapi/profiles/'+username
        }).success(function(data){
            user = data.data;
            //return user;
        });
    };*/

    this.login = function(val){
        return $http({
            method: 'GET',
            url: 'http://localhost:7070/storyBoard/webapi/stories?username='+val.username+'&password='+val.password
        }).then(function(data){
            if(data.data==="Success"){
                $rootScope.username = val.username;
                $cookies.put("username", val.username);
                $http({
                    method: 'GET',
                    url: 'http://localhost:7070/storyBoard/webapi/profiles/'+val.username
                }).success(function(data){
                    console.log(data);
                    this.user = data;
                    console.log(this.user);
                });
                $location.path("/home");
            }else{
                window.alert('Wrong username or password');
            }
        });
    };

    this.logout = function(){
        $rootScope.user.username = "";
        $cookies.remove("username");
        $location.path("/Diary");
    };

    this.addToShelf = function(wsPublish){
        wsPublish.author = $rootScope.user.username;
        return $http({
            method: 'POST',
            url:'http://localhost:7070/storyBoard/webapi/stories',
            data: wsPublish
        }).then(function(data){
            this.user.stories.push(data.data);
        });
    };
}]);

它包含3个函数和私有变量this.user以及2个rootScope变量$rootScope.username& $rootScope.user。 我们关注的功能是this.login()函数。

现在,

要使用此服务模块,我创建了一个模块AllControllers

 var app = angular.module('AllControllers',['userAngService']);

我将 2个控制器与之关联起来。

第一个控制器:

app.controller('LoginFormController',['$cookies','$rootScope','$log','$scope','userAngService','userBean',function($cookies,$rootScope,$log,$scope,userAngService,userBean){

    $scope.login = function(val){
        userAngService.login(val);
    };

    $scope.logout = function(){
        userAngService.logout();
    };

    $scope.publishGroup = function(obj){
        userBean.publishGroup(obj);
    };
}]);

*此控制器注入了userAngService的依赖关系,并且它的login()功能会委托调用login() function of userAngService服务

login()中的userAngService函数更改了其私有变量属性。 然后,我试图在另一个控制器中使用,以及所有问题所在。 当我在promise本身记录返回的userAngService数据时,它已成功记录但当我尝试在另一个控制器中访问时,它只记录空对象

第二个控制器(从那里访问服务的私有变量):

 app.controller('ReachController',['$cookies','$scope','$rootScope','userAngService',function($cookies,$scope,$rootScope,userAngService){
    $scope.user = {};
    $scope.username = {};

    $scope.user = userAngService.user;
    console.log(userAngService.user);
    $scope.username = $cookies.get("username");

    /*userAngService.loadUserData($scope.username).then(function(data){
        $scope.user = data.data;
        console.log($scope.user);
    });*/

    console.log($scope.user);
    console.log($rootScope.user);

    $scope.logout = function(){
        userAngService.logout();
    };

    $scope.addToShelf = function(wsPublish){
        userAngService.addToShelf(wsPublish);
    };
}]);

一个空对象只能意味着对象属性被定义为null并且不会被login()服务函数更新。但是,在userAndServicesuccess回调;

console.log(data);
this.user = data;
console.log(this.user);

这些代码行成功记录了返回的数据,而在ReachController第二个控制器的行中;

$scope.user = userAngService.user;
...
console.log($scope.user);

将此日志记录到控制台:

Object {}

没有错误,所以代码是正确的但是在概念上我猜错了。请帮忙!

3 个答案:

答案 0 :(得分:0)

如果您想要返回数据使用工厂而不是服务。

服务始终返回包含数据的方法。

console.log(data);
this.user = data;
console.log(this.user); 

“this”对象用于Success函数的本地范围。它会覆盖服务“这个”对象。

答案 1 :(得分:0)

我的猜测是问题在于服务和父模块的命名 - userAngService。尝试将模块重命名为userAngServiceModule。当您向userAngService添加依赖项时,无论您是指模块还是服务,我都希望angular的DI会混淆。

答案 2 :(得分:0)

promise this处理程序中的.then上下文与服务的this上下文不同。

app.service("myService", function($http) {
    var myService = this;
    this.data = {};

    this.fetch = function(url) {
        //return promise 
        return (
            $http.get(url).then (function onFulfilled(response) {
                //Won't work
                //this.data = response.data;

                //Instead use the binding
                myService.data = response.data;
                //Return data for chaining
                return myService.data;
            }).catch (function onRejected(response) {
                console.log(response.status);
                //throw to chain rejection
                throw response;
            });
        );
    };
});

this函数中的onFulfilled上下文与服务的this上下文不同。而是将服务的this上下文绑定到变量,并在promise onFulfilled方法的.then函数中使用该变量。

另请注意,this.data服务在XHR完成后的某个时间,服务的$http变量将在未来设置 。为确保数据可用,请使用fetch函数返回的承诺。

在控制器

var promise = myService.fetch(url);

promise.then (function onFulfilled(data) {
    $scope.data = data;
}).catch( function onRejected(errorResponse) {
    console.log(errorResponse.status);
});