在多个控制器中使用AngularJs服务

Using AngularJs Service in more than one controllers

本文关键字:AngularJs 服务 控制器      更新时间:2024-01-30

我在这里与angular作斗争。我学到的是,模块的工厂和服务功能只创建一个对象的实例,将属性(函数和变量)与之关联。该实例在应用程序的整个控制器中都可用。

在我的应用程序中,我创建了一个服务模块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个函数和私有变量CCD_ 2和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服务

userAngService中的login()函数更改其私有变量属性。然后我试图在另一个控制器中使用它,这就是所有问题所在。当我将返回的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 {}

没有错误,所以代码是对的,但我想概念上有问题。请帮忙!

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

服务总是返回带有数据的方法。

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

"this"对象用于Success函数的本地范围。它将覆盖服务"this"对象。

我的猜测是,问题出在服务和父模块userAngService的相同命名上。尝试将模块重命名为userAngServiceModule。当您向this.user0添加依赖项时,我预计angular的DI会混淆您指的是模块还是服务。

promise .then处理程序中的this上下文与服务的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;
            });
        );
    };
});

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

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

在控制器中

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