2015-07-19 15 views
5

Sono totalmente nuovo per angularjs e ionico. Provo a memorizzare 4 valori che ricevo da una chiamata di fabbrica in 4 variabili che ho bisogno di usare come parametri per la mia chiamata http http in un'altra funzione:Angularjs: memorizza i dati in variabili da una chiamata di fabbrica da utilizzare in un'altra chiamata di fabbrica

ecco le 4 variabili definite all'inizio del mio controller:

var firstId; 
var firstTimestamp; 
var lastId; 
var lastTimestamp; 

ricevo i dati dalla seguente chiamata alla mia fabbrica e assegnare i dati alle variabili:

ContentFactory.getAlbums().then(function(albums){ 

    $scope.albums = albums; 

    firstId = albums.first_id; 
    firstTimestamp = albums.first_timestamp; 
    lastId = albums.last_id; 
    lastTimestamp = albums.last_timestamp; 
}); 

cerco quindi di utilizzare queste variabili come parametri per un'altra chiamata alla mia fabbrica (loadOlderAlbums è chiamato nella vista):

$scope.loadOlderAlbums = function(lastId, lastTimestamp) { 
ContentFactory.getOlderAlbums(lastId, lastTimestamp).then(function(albums){ 
    $scope.albums = $scope.albums.concat(albums); 
    $scope.$broadcast('scroll.infiniteScrollComplete'); 
}); 
}; 

Le variabili lastId & lastTimestamp sono indefiniti al momento del check la mia fabbrica:

getOlderAlbums : function(lastId, lastTimestamp){ 
     console.log(lastId); // lastId is undefined 
     return $http.get('http://api.domain.xxx/albums/city/1? &direction=before&id=' + lastId + '&time=' + lastTimestamp + '&api_key=******&lang=en').then(function(response) { 
       albums = response.data; 
       return albums; 
     }); 
    } 

nella console vedo il seguente errore:

GET http://api.domain.xxx/albums/city/1?&direction=before&id=undefined&time=undefined&api_key=***&lang=en 500 (Internal Server Error) 

perché id & tempo sono indefiniti.

qui è il controller completo:

.controller('PicturesCtrl', function($scope, $ionicLoading, ContentFactory) { 

$scope.albums = []; 

var firstId; 
var firstTimestamp; 
var lastId; 
var lastTimestamp; 

ContentFactory.getAlbums().then(function(albums){ 
    $scope.albums = albums; 
    firstId = albums.first_id; 
    firstTimestamp = albums.first_timestamp; 
    lastId = albums.last_id; 
    lastTimestamp = albums.last_timestamp; 

    // console.log(firstId); -> values are correctly stored 
    // console.log(firstTimestamp); -> values are correctly stored 
    // console.log(lastId); -> values are correctly stored 
    // console.log(lastTimestamp); -> values are correctly stored 

}); 


$scope.loadOlderAlbums = function(lastId, lastTimestamp) { 
ContentFactory.getOlderAlbums(lastId, lastTimestamp).then(function(albums){ 
    $scope.albums = $scope.albums.concat(albums); 
    $scope.$broadcast('scroll.infiniteScrollComplete'); 
}); 
}; 

}) 

e la fabbrica:

.factory('ContentFactory', function($http) { 

var albums = []; 

return { 



    getAlbums : function(){ 
     return $http.get('http://api.domain.xxx/albums/city/1?lang=en&api_key=***').then(function(response) { 
       albums = response.data; 
       return albums; 
     }); 
    }, 


    getOlderAlbums : function(lastId, lastTimestamp){ 
     console.log(lastId); // lastId is undefined 
     return $http.get('http://api.domain.xxx/albums/city/1?&direction=before&id=' + lastId + '&time=' + lastTimestamp + '&api_key=***&lang=en').then(function(response) { 
       albums = response.data; 
       return albums; 
     }); 
    } 
    } 
}) 

Qualsiasi aiuto per capire il motivo per cui il valore delle variabili non sono passati alla seconda chiamata fabbrica sono molto apprezzati . La sua probabilmente un problema di logica come io sono un newbie totale;)

UPDATE:

Di seguito riportiamo una risposta campione che ho ricevuto dal mio primo $ http GET chiamare Content.Factory.getAlbums

{ 
"city_id": 1, 
"total_pages": 199, 
"total_results": 3977, 
"first_id": 15448, 
"first_timestamp": 1437230820, 
"results": [ 
    { 
     "album_id": "15448", 
     "title": "MAD pres. Splash The Madness Party at Aftermoon", 
     "description": "The MAD crew is back and returned to Aftermoon for a night of Melbourne Bounce, Hip Hop, Big Room, Electro- and Progressive House. At the decks were Dam-Sib-Dao, Beatender, Madz Mellow & Odyszey, supported by Mc Ben10.", 
     "photographer_id": "8", 
     "photographer_name": "ploy", 
     "image_count": "88", 
     "cover_image": "5dd26da7f37da641d775568d2e98ae44.jpg", 
     "date": "2015-07-18 21:47:00", 
     "location_id": "705", 
     "location_name": "Aftermoon" 
    }, 
    { 
     "album_id": "15446", 
     "title": "Superhero Charity Party at KU DÉ TA Bangkok", 
     "description": "KU DÉ TA Bangkok and the charity organisation \"Habitat for Humanity Thailand\" joined forces for the SUPERHERO “CHARITY PARTY\". Habitat for Humanity Thailand improves the quality of Thai people’s lives through building homes and transforming communities. Entry is Free, but there guests are invited to do a FREE-WILL DONATION of which 100% will go to Habitat for Humanity Thailand to build houses under the program “Make Her Day” in Pathumthani.", 
     "photographer_id": "15", 
     "photographer_name": "win", 
     "image_count": "176", 
     "cover_image": "742a0065d046418041175ff8005d7174.jpg", 
     "date": "2015-07-18 18:46:00", 
     "location_id": "809", 
     "location_name": "KU DÉ TA" 
    } 
], 
"last_id": 15427, 
"last_timestamp": 1437062520 
} 

Il $ scope.loadOlderAlbums è chiamato a mio avviso (ionica infinite scroll)

<ion-infinite-scroll 
    on-infinite="loadOlderAlbums()" 
    distance="1%"> 
</ion-infinite-scroll> 
+0

$ scope.album viene effettivamente caricato? Sarebbe d'aiuto se potessi mostrarci cosa viene effettivamente caricato in $ scope.Album. –

+0

Dove stai effettivamente chiamando '$ scope.loadOlderAlbums()'? Sarebbe il primo posto da cercare se gli argomenti non sono definiti quando lo chiami – charlietfl

+0

Installa batarang in modo che tu possa esaminare e confrontare gli ambiti. –

risposta

1

cambiare il metodo di portata $ per prendere gli album più vecchi. Ci si aspetta che i parametri vengano inoltrati, ma nel momento in cui lo si chiama dovrebbero già essere definiti nell'ambito del controllore, quindi non c'è davvero bisogno di farlo.

E visto che non si sta esponendo il lastId o lastTImestamp su thiso$scope, che mi porta a credere che a suo avviso si sta chiamando il metodo in questo modo:

<button ng-click="loadOlderAlbums()">Load more albums</button> 

Nel qual caso , lastId e lastTimestamp non sono mai stati passati alla funzione $ scope, e non funzionerà.

Qualcosa di simile dovrebbe farlo:

$scope.loadOlderAlbums = function() { 
ContentFactory.getOlderAlbums(lastId, lastTimestamp).then(function(albums){ 
    $scope.albums = $scope.albums.concat(albums); 
    $scope.$broadcast('scroll.infiniteScrollComplete'); 
}); 
}; 

Ora, non dovrà passare lastId o lastTimestamp nella vostra funzione (come hai precedentemente richiesto).


Se siete certi che il getAlbums() chiamata ha sparato prima di iniziare lo scorrimento, il seguente dovrebbe funzionare bene (redatto un mucchio di codice per evidenziare il punto principale):

var lastId, lastTimeStamp: 

getAlbums().then(function (res) { 
    lastId = res.lastId; 
    lastTimeStamp = res.lastTimeStamp; 
}); 

/** Later, called from the view **/ 
function loadOlderAlbums() { // <-- Kill the arguments. 
    $http.get('path' + lastId + lastTimeStamp).then(function (res) { 
    /** woop woop! **/ 
    }); 
} 

Altrimenti, è necessario configurare un sistema di sicurezza per tale scenario. Si potrebbe o andare con un'altra promessa, o qualcosa di molto semplice in questo modo, per il momento possibilmente escluderlo:

var loaded = false; 

function getAlbums() { 
    $http.get('albums').then(function (res) { 
    /** set the ID's and timestamps **/ 
    loaded = true; 
    }); 
} 

function loadOlderAlbums() { 
    if (!loaded) { 
    throw new Error('Yep, nope. We have to get some other albums first. Sorry!'); 
    } 

    /** your old loadOlderAlbums implementation **/ 
} 

Aggiungendo che throw dichiarazione in là, è possibile verificare che ci sia:

  • O una condizione di competizione nella memorizzazione (tramite getAlbums)/utilizzo (tramite loadOlderAlbums) delle variabili lastId e lastTimeStamp.
  • Oppure magicamente ha iniziato a funzionare.

Dal momento che si sta utilizzando ionico - che a sua volta utilizza ui-router; È possibile trasferire la chiamata a getAlbums in un resolve block e si farebbe in modo che i dati vengano caricati nel controller prima di iniziare a scorrere.

Questo potrebbe essere simile:

.state('...', { 
    controller: 'PicturesCtrl', 
    resolve: { 
    preloadedAlbums: function (ContentFactory) { // available for DI later into your controller. 
     return ContentFactory.getAlbums().then(function (response) { 
     return { 
      albums: response, 
      firstId: response.first_id, 
      firstTimeStamp: response.first_timestamp, 
      lastId: response.last_id, 
      lastTimeStamp: response.last_timestamp 
     }; 
     }); 
    } 
    } 
} 

Ora, ogni volta che si tenta di accedere a detto stato - l'oggetto determinazione avrà il suo roba prima che il controllore venga invocato. Pertanto, si garantisce che i dati siano presenti prima che l'utente inizi a scorrere nell'ambito del proprio PicturesCtrl e che i parametri richiesti per loadMoreAlbums siano presenti.

tuo PicturesCtrl potrebbe ora guardare qualcosa sulla falsariga di:

.controller('PicturesCtrl', function ($scope, $ionicLoading, ContentFactory, preloadedAlbums) { 

    $scope.albums = preloadedAlbums; 

    var lastId = preloadedAlbums.lastId; 
    var lastTimeStamp = preloadedAlbums.lastTimeStamp; 
    /** etc **/ 
}); 

vorrei provare il primo suggerimento (con un throw) per assicurare che si tratta di una questione di getAlbums promessa di non avere stato risolto che sta causando il tuo problema. Quindi prenderei in considerazione la possibilità di passare a un blocco resolve.


Se questo non sradicare la causa dei vostri problemi, vorrei saltare la base di codice con debugger 's e scorrere dall'inizio alla fine di verificare che cosa è in realtà in corso.

+2

Caro Kaspar, grazie per aver cercato di aiutarmi, lo apprezzo davvero. – Menelik

+0

Ho appena visto le modifiche che hai apportato alla tua domanda, sembrerebbe che avevo ragione sul denaro :) Se chiami la funzione come se l'avessi implementata (nel controller) in questo momento (dalla vista) senza parametri passati - 'lastId' e' lastTimestamp' ** saranno ** indefiniti. –

+0

Sì, il metodo è chiamato a mio avviso (fa parte dello scroll infinito ionico). Ho aggiornato la mia domanda per includere la parte vista. lastId e lastTimestamp fanno parte della prima risposta GET di ContentFactory.getAlbums(). Ho provato a cambiare il mio codice per includere i tuoi suggerimenti ma non funziona ancora. Nella seconda chiamata alla mia API lastId e lastTimestamp sono ancora indefiniti. Qualsiasi altro aiuto sarebbe molto apprezzato. – Menelik

Problemi correlati