2013-03-01 18 views
14

Ho riscontrato un problema nel recupero dei dati da un servizio inserito nella vista personale. Ho un servizio definito come taleAngularJS Carica dati dal servizio

app.factory('nukeService', function($rootScope, $http) { 
    var nukeService = {}; 

    nukeService.nuke = {}; 

    //Gets the list of nuclear weapons 
    nukeService.getNukes = function() { 
     $http.get('nukes/nukes.json') 
      .success(function(data) { 
       nukeService.nukes = data; 
      }); 

     return nukeService.nukes; 
    }; 

    return nukeService; 
}); 

e il mio controller

function NavigationCtrl($scope, $http, nukeService){ 



    /*$http.get('nukes/nukes.json').success(function(data) { 
     $scope.nukes = data; 
    });*/ 

    $scope.nukes = nukeService.getNukes(); 

} 

Se uso il $ http.get dal controllore dei dati popola bene, tuttavia, se provo a chiamare i dati il servizio, non ottengo nulla. Capisco che la query sia asincrona, ma sto avendo difficoltà a capire come popolare la variabile $ scope una volta che i dati vengono restituiti. Potrei usare $ rootscope per trasmettere un evento e ascoltarlo nel controller, ma questo non sembra il modo corretto per farlo. Gradirei davvero qualche consiglio su come farlo nel modo corretto.

risposta

27

credo che questo dovrebbe risolvere il tuo problema

app.factory('nukeService', function($rootScope, $http) { 
    var nukeService = {}; 

    nukeService.data = {}; 

    //Gets the list of nuclear weapons 
    nukeService.getNukes = function() { 
     $http.get('nukes/nukes.json') 
      .success(function(data) { 
       nukeService.data.nukes = data; 
      }); 

     return nukeService.data; 
    }; 

    return nukeService; 
}); 

function NavigationCtrl($scope, $http, nukeService){ 

    $scope.data = nukeService.getNukes(); 

    //then refer to nukes list as `data.nukes` 

} 

Questo è un problema con riferimento a un oggetto.

quando si chiama nukeService.getNukes() si ottiene un riferimento a un oggetto a quindi la variabile $scope.nukes fa riferimento a tale posizione di memoria.

Dopo la chiamata server remoto quando si imposta nukeService.nukes = data; non si modifica l'oggetto a invece si cambia nukeService.nukes da riferimento all'oggetto a di opporsi b. Ma il tuo $scope.nukes non sa di questa riassegnazione e punta ancora all'oggetto a.

mia soluzione in questo caso è di passare un oggetto a con struttura data e modificare solo la proprietà data invece di cambiare riferimento a

+0

che ha funzionato, ma posso chiedere perché? Presumo che abbia qualcosa a che fare con .data è un contenitore per i dati JSON invece di provare a passarlo direttamente? A proposito, grazie per la pronta risposta! – jamesamuir

+0

se funziona si prega di contrassegnare la risposta come accettato –

+0

contrassegnato come risposta. grazie per la spiegazione. – jamesamuir

9

Questo dovrebbe essere la seguente. Come menzionato dal commento di NickWiggill, undefined verrà assegnato a nukeService.data se non restituiremo la promessa.

3

Quello che faccio è che espongo i dati direttamente dal servizio, e ho un metodo che inizializza questi dati. Cosa c'è di sbagliato in questo?

Servizio:

app.factory('nukeService', function($scope, $http) { 
    var data = {}; 
    data.nukes = []; 

    //Gets the list of nuclear weapons 
    var getNukes = function() { 
     $http.get('nukes/nukes.json').success(function(data) { 
       data.nukes = data; 
     }); 
    }; 

    // Fill the list with actual nukes, async why not. 
    getNukes(); 

    return { 
     data : data 
     // expose more functions or data if you want 
    }; 
}); 

Controller:

function NavigationCtrl($scope, nukeService){ 
    $scope.data = nukeService.data; 
    //then refer to nukes list as `$scope.data.nukes` 
}