2013-04-14 84 views
0

如何在我设置它的函数之外使用totalResults?我只是不知道如何做到这一点,我需要使用从我的数据库中收集的totalResults,并使用另一个函数来计算页面数量。我这样做,所以我不加载所有的数据到客户端,但我仍然需要知道数据库表中的行数。

我的JSON的样子:

Object {total: 778, animals: Array[20]} 

角:

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

app.controller('AnimalController', ['$scope', 'animalSrc', function($scope, animalSrc) 
{ 
    $scope.animals = []; 

    var skip = 0; 
    var take = 20; 
    var totalResults = null; 
    //$scope.totalResults = null; 

    $scope.list = function() 
    { 
     animalSrc.getAll(skip, take, function(data) { 
      $scope.animals = $scope.animals.concat(data.animals); 

      // I need to be able to use this outside of function ($scope.list) 
      totalResults = data.total; 
      //$scope.totalResults = data.total; 
     }); 
    }; 

    $scope.showMore = function() 
    { 
     skip += 20; 
     $scope.list(); 
    }; 

    $scope.hasMore = function() 
    { 
     // 
    }; 

    // Outputs null, should be the total rows from the $http request 
    console.log(totalResults); 
}]); 

app.factory('animalSrc', ['$http', function($http) 
{ 
    // Private // 

    return { 
     getAll: function(skip, take, callback) 
     { 
      $http({ 
       method: 'GET', 
       url: 'url' + skip + '/' + take 
      }). 
      success(function(data) { 
       callback(data); 
      }). 
      error(function(data) { 
       console.log('error: ' + data); 
      }); 
     } 
    }; 
}]); 
+0

你的代码应该是工作,执行console.log调用将总是先totalData变量设置 – jusio

+0

它打印空,因为它被称为确实有效,但是我怎样才能获得控制器底部的console.log,以便从$ http请求中更新我的总数,以便我可以使用它? – dynamo

+0

只要您在控制器内发送请求,底部的console.log永远不会输出总计数。如果你想更新页数,你应该在回调中做到这一点。如果你想在另一个函数中做到这一点,你应该从回调 – jusio

回答

1

你需要开始思考异步。您的console.log在$ http返回并且设置了totalResults之前被调用。因此,totalResults将始终为空。

您需要找到某种方式来延迟对console.log的调用,以便在运行console.log之前完成$ http调用。一种方法是将console.log调用放入回调函数中,以便在$ http成功后明确调用它。

更好的方法是使用承诺。 angular.js实现$ q,这与Q是一个承诺库类似。

http://docs.angularjs.org/api/ng.$q

而不用在GETALL一个回调函数,返回一个承诺。在$ http成功内部,您可以用数据解决承诺。然后,在您的控制器中,您有一个在解决承诺时调用的函数。 Promise很好,因为它们可以被传递,它们允许你在不阻塞的情况下控制异步代码的流程。

+0

我认为它与此有关,但从我的理解中我认为$ http已经回复了承诺? – dynamo

+0

$ http基于承诺库,但是我发现拥有$ q.defer()对象会更优雅 - 这样您就可以将您在服务和控制器中执行的操作分开。您可以通过向函数添加回调来实现承诺的相同功能,这就是为什么将console.log添加到回调结束时的原因。 – Destron

1

以下是我正在为自己设计的样板,其中数据是需要拆分为多个范围项目的对象。您没有把握的问题是将数据存储在服务中,而不仅仅是使用服务来检索数据。然后数据项在multple控制器和指令可通过注射服务

app.run(function(MyDataService){ 
    MyDataService.init(); 
}) 

app.factory('MyDataService',function($http,$q){ 

    var myData = { 
    deferreds:{}, 

    mainDataSchema:['count','items'], 
    init:function(){ 
     angular.forEach(myData.mainDataSchema,function(val,idx){ 
     /* create deferreds and promises*/ 
     myData.deferreds[val]=$q.defer(); 
     myData[val]= myData.deferreds[val].promise 
     });  
     /* load the data*/ 
     myData.loadData(); 

    },  

    loadData:function(){ 
     $http.get('data.json').success(function(response){ 
      /* create resolves for promises*/ 
      angular.forEach(myData.mainDataSchema,function(val,idx){    
      myData.deferreds[val].resolve(response[val]); 
     }); 
     /* TODO -create rejects*/ 

     }) 

    } 
    } 

    return myData; 

    }) 

app.controller('Ctrl_1', function($scope,MyDataService) { 
    $scope.count = MyDataService.count; 
    $scope.items =MyDataService.items; 
}); 

app.controller('Ctrl_2', function($scope,MyDataService) { 
    $scope.items =MyDataService.items; 
    $scope.count = MyDataService.count; 
}); 

Plunker demo

相关问题