【问题标题】:Ionic AngularJS http on service do not update controller服务上的 Ionic AngularJS http 不更新控制器
【发布时间】:2015-11-13 06:31:18
【问题描述】:

这可能是因为我不确定如何使用 Promise,但是在我调用触发 http 调用的服务之后,在我的控制器中结果是空数组.. 为什么会这样? 我的应用设置如下:

这是 app.js

//App.js
  .state('myApp.sermonlists', {
    url: "/sermonlists",
    views: {
      'menuContent': {
        templateUrl: "templates/sermonlists.html",
        controller: 'SermonListsCtrl'
      }
    }
  })

这是controller.js

//controller.js
angular.module('myApp.controllers', [])
.controller('SermonListsCtrl', function($scope, sermonListsService) {
  // call sermon api
  sermonListsService.getSermonLists(); // this return empty array()
})

这是 services.js

//services.js
angular.module('myApp.services', [])

.factory('sermonListsService', function($http) {
    var sermon = [];

    function sermonJson() {
        $http.get('http://myapicall.com').then(function(resp) {
          // For JSON responses, resp.data contains the result
          sermon = resp.data;
         }, function(err) {
          console.error('ERR', err);
          // err.status will contain the status code
        })          
    }

    // initializing sermonJson call
    function init() {
        sermonJson();
    }

    // run init()
    init();

    return {
        getSermonLists: function(){

            return sermon;
        },
        getUser: function(index){
            return "";
        }
    }
})

这方面的最佳做法是什么?如果你能帮我解决这个问题,那就太好了,还有例子

【问题讨论】:

标签: javascript angularjs ionic-framework ionic promise


【解决方案1】:

您已经为控制器和服务创建了不同的模块,因此它们没有被注入。要注入它们,你要么管理它的依赖,要么你可能需要使模块相同

试试下面

//controller.js
angular.module('myApp', [])
     .controller('SermonListsCtrl', function($scope, sermonListsService) {
     // call sermon api
      sermonListsService.getSermonLists(); // this return empty array()
});


//services.js
 angular.module('myApp', [])

 .factory('sermonListsService', function($http) {
   var sermon = [];

    function sermonJson() {
    $http.get('http://myapicall.com').then(function(resp) {
      // For JSON responses, resp.data contains the result
      sermon = resp.data;
     }, function(err) {
      console.error('ERR', err);
      // err.status will contain the status code
    })          
}

// initializing sermonJson call
function init() {
    sermonJson();
}

// run init()
init();

return {
    getSermonLists: function(){

        return sermon;
    },
     getUser: function(index){
        return "";
     }
   }
 })

【讨论】:

    【解决方案2】:

    问题是,getSermonLists() 返回一个对空数组的引用(最初是可以的),但是 $http 回调并没有填充数组,而只是替换了内部列表。 getSermonLists() 的返回值仍然引用空数组,即使服务中的“var sermon”现在引用填充数组。

    使用相同的数组实例

    首先,您可以更改 $http 回调以获取响应的所有元素并将它们推送到数组,而不仅仅是更改引用。即:

    $http.get(...).then(function(response) {
        // Add all elements of response.data to sermon, you could also use a loop here
        sermom.push.apply(sermon, response.data)
    });
    

    这也会改变控制器列表,因为列表仍然是同一个实例。

    使用承诺

    第二种方法是使用承诺,正如您已经建议的那样。在这种情况下,getSermonLists 不应该返回一个数组,而是一个处于未解析状态的 Promise,直到 ajax 调用完成。 Angular 使用$q 服务来创建承诺:

    var sermon = $q.defer();
    function sermonJson() {
        sermon = $http.get(....).then(function(response) {
            sermon.resolve(response.data);
        });
    }
    
    getSermonList: function() {
        return sermon;
    }
    

    并更改您的控制器以使用承诺:

    sermonListsService.getSermonLists().then(function(sermonList) {
        // Do something with sermonList, e.g. $scope.sermons = sermonList;
    });
    

    Promises 允许控制器等待布道被加载并在之后做一些事情,它可以处理请求失败的情况。

    【讨论】:

    • 为什么要重新定义sermon?第一个var sermon = $q.defer(); 第二个sermon = $http.get(....)?
    • @Grundy 您是否介意使用 ionic/angularjs 风格的最佳实践为此编写一个解决方案。谢谢
    猜你喜欢
    • 2015-12-17
    • 2013-03-24
    • 2015-02-28
    • 2014-09-14
    • 2016-05-14
    • 2014-11-27
    • 2017-10-11
    • 1970-01-01
    • 2015-05-14
    相关资源
    最近更新 更多