简体   繁体   English

在多个控制器中使用AngularJs Service

[英]Using AngularJs Service in more than one controllers

I am struggling with angular here. 我在这里挣扎着角。 What I learned is that factory and service functions of a module create only one instance of an object associating properties ( functions and variables) with it. 我学到的是模块的工厂和服务功能只创建一个对象的一个​​实例,它将属性(函数和变量)与它相关联。 And that that instance is available throughout the controllers of the application. 并且该实例可在整个应用程序的控制器中使用。

In my app I have created a service module userAngService as follows: 在我的应用程序中,我创建了一个服务模块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);
        });
    };
}]);

It contains 3 functions and private variable this.user and 2 rootScope variables $rootScope.username & $rootScope.user . 它包含3个函数和私有变量this.user和2个rootScope变量$rootScope.username$rootScope.user Our concerned function is this.login() function here. 我们关心的函数是this.login()函数。

Now, 现在,

To use this service module I created a module AllControllers : 要使用此服务模块,我创建了一个模块AllControllers

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

and I associated 2 controllers with it. 我用它关联了2个控制器

First controller: 第一控制器:

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);
    };
}]);

*This controller is injected with dependency of userAngService and it's login() function delegates a call to login() function of userAngService service *此控制器注入了userAngService依赖userAngService ,它的login()函数委托调用login() function of userAngService服务的login() function of userAngService

The login() function in userAngService changes its private variables properties. userAngServicelogin()函数更改其私有变量属性。 Which then I am trying to use in another controller and that's where all the problem is. 然后我试图在另一个控制器中使用,这就是所有问题所在。 When I am logging the returned promise data in userAngService itself, it is logging successfully but when I try to access in another controller, it just logs an empty object 当我在userAngService本身记录返回的promise数据时,它已成功记录但是当我尝试访问另一个控制器时,它只记录一个空对象

Second Controller (from where accessing the service's private variables) : 第二个控制器(从那里访问服务的私有变量):

 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);
    };
}]);

Well an empty object can only mean that the object properties are defined to null and are not updated by login() function of service. 那么一个空对象只能意味着对象属性被定义为null并且不会被login()函数更新。 However, in userAndService withing success callback; 但是,在userAndService success回调;

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

these lines of code successfully log returned data, while in ReachController or Second Controller 's lines; 这些代码行成功记录返回的数据,而在ReachControllerSecond Controller的行中;

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

logs this to console: 将此记录到控制台:

Object {}

There are no errors so code is right but then something wrong conceptually I guess. 没有错误,所以代码是正确的,但在概念上我猜错了。 Please help! 请帮忙!

if you want to return a data use factory instead of service. 如果要返回数据使用工厂而不是服务。

Service always returns a methods with data. 服务始终返回包含数据的方法。

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

"this" object is for local scope of Success function. “this”对象用于Success函数的局部范围。 it will overridden service "this" object. 它将覆盖服务“this”对象。

My guess is that the problem is in the same naming of service and parent module - userAngService . 我的猜测是问题在于服务和父模块的命名 - userAngService Try renaming module to userAngServiceModule . 尝试将模块重命名为userAngServiceModule I would expect angular's DI to get confused whether you are referring to module or service when you add dependency to userAngService . 当你向userAngService添加依赖时,无论你是指模块还是服务,我都希望angular的DI会混淆。

The this context inside a promise .then handler is not the same as the this context of a service. 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;
            });
        );
    };
});

The this context in the onFulfilled function is not the same as the this context of the service. this背景下的onFulfilled的功能是不一样的this服务的环境。 Instead bind the this context of the service to a variable and use that variable in the onFulfilled function of the promise .then method. 相反,结合this服务的情况下,以一个变量并使用该变量在onFulfilled承诺的功能.then方法。

Also be aware that this.data variable of the service gets set in the future sometime after the XHR by the $http service completes. 另外要注意, this.data服务的变量被用在XHR之后的某个时间设定在未来 $http服务完成。 To be sure the data is available, use the promise that the fetch function returns. 要确保数据可用,请使用fetch函数返回的promise。

In the controller 在控制器中

var promise = myService.fetch(url);

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM