在控制器之间共享数据从服务异步获取/设置数据 - AngularJS

时间:2016-06-28 06:46:48

标签: angularjs angularjs-scope angularjs-controller

我无法使自定义角度服务工作。

我的服务如下:

app.service('userService', function(){
  var user = [];

  var setUser = function(newObj){
    user.push(newObj);
  };

  var getUser = function(){
    return user;
  };

  return {
    setUser: setUser,
    getUser: getUser
  };
});

app.config(function($routeProvider,$locationProvider) {

  $routeProvider
    .when('/', {
      templateUrl : 'views/home.html',
      controller  : 'indexController'
    })
    .when('/me.html', {
      templateUrl : 'views/me.html',
      controller  : 'meController'
    });

    // Get rid of the additional default pound sign during routing
    $locationProvider.html5Mode(true);
});

我将其称为如下

app.controller('indexController', function($http,userService) {  
                                ...
    $http.post("somewhere")
        .then(function(response){
           userService.setUser({test: "test});
           location="/me.html";
        }
        .then(function(response){
           userService.setUser({test: "test});
           location="/me.html";
        })
});

当我在另一个控制器中执行console.log时,它返回一个空数组。我搞砸了什么?

app.controller('meController',function($http,userService){
   console.log(userService.getUser()); => returns an empty array []

});

修改 我的一些代码含糊不清,添加了我的路线部分,应该更清楚一些。 编辑2 忘了提一下,如果我在setUser()后面的行中放入console.log(userService.getUser()),它会正确显示数据。

即。

$http.post("somewhere")
    .then(function(response){
       userService.setUser({test: "test});
       location="/me.html";
    }
    .then(function(response){
       userService.setUser({test: "test});
       location="/me.html";
       console.log(userService.getUser()); => correct output
    })

2 个答案:

答案 0 :(得分:0)

可能因为console.log指令在从另一个控制器分配之前运行。

你可以通过以下方式修复它:

  1. 实施回调系统
  2. $ scope.watching service.getUser()
  3. 在服务中实施承诺
  4. 使用$broadcast / $emit
  5. 实施信号系统

    对于案例1.您可以这样做:

    app.service('userService', function(){
      var user = [],callbacks = [];
    
      var setUser = function(newObj){
        user.push(newObj);
        for(var i = 0;i< callbacks.length;++i)
          callbacks[i](user);
      };
    
      var getUser = function(){
        return user;
      };
    
      var onUserChange = function(callback) {
        callbacks.push(callback);
      };
    
      return {      
        onUserChange:onUserChange,
        setUser: setUser,
        getUser: getUser
      };
    });
    

    然后尝试在第二个控制器中调用它。

    案例2。

    app.controller('meController',function($http,$scope,userService){
      $scope.$watch(function(){ return userService.getUser(); },
                    function(newvalue){ console.log(newvalue); },
                    true);
    
    });
    

答案 1 :(得分:0)

对于我的项目,我通常会将所有$http放在相应的服务中,并在需要在外部调用时公开函数。

app.service('userService', function(){
  var user = [];
  var isReady = false;

  var setUser = function(newObj){
    user.push(newObj);

    $http(...).then(function(){}, failHandler);

    function failHandler() {
      // undo the push and show error to user
    }
  };

  var getUser = function(){
    if (isReady) {
      return $q.when(user);
    }
    else {
      return $http(...).then(function(data){
        user = data.xxx;
        isReady = true;
      });
    }
  };

  return {
    setUser: setUser,
    getUser: getUser
  };
});

请注意,getUser现在正在返回一个承诺,因此您需要使用.then来处理事情。

您也可以将setUser更改为承诺,以便在控制器端显示成功或错误。