0

我正在迁移我的 Angular 1.x 代码以使用更新、更首选的语法,避免使用 $scope 并将控制器用作语法。不过,我在从服务获取数据时遇到问题。

这是我的例子:

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

myApp.controller('MainCtrl', ['$http', '$location', 'userService',
  function($http, $location, userService) {

    this.name = 'John Doe';

    // this.userData = {

    // }

    this.userData = userService.async().then(function(d) {
      return d;
    });


    console.log(this.userData);


  }
]);

myApp.service('userService', function($http) {

  var userService = {
    async: function() {
      // $http returns a promise, which has a then function, which also returns a promise
      var promise = $http.get('https://jsonplaceholder.typicode.com/users').then(function(response) {
        // The then function here is an opportunity to modify the response
        // console.log(response);
        // The return value gets picked up by the then in the controller.
        return response.data;
      });
      // Return the promise to the controller
      return promise;
    }
  };
  return userService;

});
<body ng-app="myApp">
  <div id="ctrl-as-exmpl" ng-controller="MainCtrl as mainctrl">

    <h1>Phone Numbers for {{mainctrl.name}}</h1>

    <button ng-click="">newest</button>
    <p>{{mainctrl.userData}}</p>
    <ul>
      <li ng-repeat="users in mainctrl.userData">{{users.phone}} -- {{users.email}}</li>
    </ul>
  </div>
</body>

我遇到的这个问题是,从 userService.async 返回的数据是一个对象,我似乎无法深入了解从中获取数据,因为数据是 $$state 的子对象,它不能似乎在视图中使用。

如果这不是在 Controller As/$scope-less 语法中使用服务的正确方法,那么正确的方法是什么?

现场示例:http: //plnkr.co/edit/ejHReaAIvVzlSExL5Elw ?p=preview

4

2 回答 2

1

你错过了 Promise 的一个重要部分——当你从一个 Promise 返回一个值时,你返回一个新的 Promise,它将解析为这个值。

当前将 promise 返回的数据设置为控制器中的局部变量的方法是:

myApp.controller('MainCtrl', ['$http', '$location', 'userService',
  function($http, $location, userService) {

    this.name = 'John Doe';

    userService.async().then(function(d) {
      this.userData = d;
    });
  }
]);

但是现在您因为 的范围而陷入困境this,因此通常将“占位符”变量用于控制器this范围。

myApp.controller('MainCtrl', ['$http', '$location', 'userService',
  function($http, $location, userService) {

    var $ctrl = this; // Use $ctrl instead of this when you want to address the controller instance

    $ctrl.name = 'John Doe';

    userService.async().then(function(d) {
      $ctrl.userData = d;
    });
  }
]);
于 2016-12-14T15:23:40.397 回答
0
this.userData = userService.async().then(function(d) {
  return d;
});

在这段代码this.userData中实际上被定义为一个承诺。如果你想要返回的数据,你需要使用你喜欢的d参数:.then function

userService.async().then(function(d){
    this.userData = d;
    //a console.log() here would determine if you are getting the data you want.  
});

编辑 我刚刚在你的服务中注意到你已经.data在你的响应对象上使用了。

老实说,我对您的最佳建议是从http.get()您的服务内部的调用中返回承诺,如下所示:

myApp.service('userService', function($http) {
    var userService = {
        async: function() {
          return $http.get('https://jsonplaceholder.typicode.com/users');
        }
    };
    return userService;

});

然后你可以使用这样的东西来捕获和利用响应数据:

userService.async().then(function(response){
    this.userData = response.data;
);

这可能是一个更清洁的解决方案

于 2016-12-14T15:00:29.967 回答