1

Ich versuche, einen Ajax-Anruf über $http Service in einem benutzerdefinierten Dienst zu tun. Dann möchte ich in meinem Controller die Daten anpassen, die im benutzerdefinierten Dienst empfangen werden.Angular Async-Dienst

Ich wickeln die Customizing-Datenfunktion innerhalb $interval in der Steuerung: Auf diese Weise kann ich meine Daten anpassen, wenn es empfangen wird.

Das Problem ist: Während die Daten korrekt in dem Dienst angemeldet sind, der Service scheint, wie es nichts zurückliefert, obwohl es (return response.data.Items)

$interval Schleifen unbegrenzt So hätte zurückgeben sollen, und ich kann meine Daten nicht anpassen.

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


myApp.service('ajaxcall', ['$http', function($http) { 

    this.getjson = function() { 

     $http.get("http://localhost:3000/one") 
      .then(function(response) { 

      console.log(response.data.Items); //data logged correctly 
      return response.data.Items; 
     }); 
    } 
}]) 

.controller('MyCtrl', ['$scope', '$interval', 'ajaxcall', function($scope, $interval, ajaxcall) { 

    var new_items = ajaxcall.getjson(); 

    customize_data = $interval(function() { //loops indefintely, new_items=undefined, why? 
         if (new_items) { 
          // customize data 
         } 
        }, 200); 

    for(var i=0; i<new_items.length; i++) { 
     $scope.items.push(new_items[i]); 
    } 
}]); 

Sie könnten sagen: Verschieben Sie einfach die benutzerdefinierte Datenfunktion im benutzerdefinierten Dienst. Zuerst möchte ich es nicht tun. Zweitens macht es nicht einmal Sinn: Der $ scope ist in einem Service nicht verfügbar, also sollte ich in jedem Fall auf die $ http-Antwort warten.

+1

Verwendung Versprechen in Ihrem Dienst nutzt –

Antwort

1

Es gab einige Dinge, die ich dort darauf hin wollte.

  1. Do $http Versprechen von this.getjson Methode zurückkehren, so dass Sie Kette, die versprechen, während die Daten von ihm zu bekommen.

    this.getjson = function() { 
        //returned promise here 
        return $http.get("http://localhost:3000/one") 
        .then(function(response) { 
        console.log(response.data.Items); //data logged correctly 
        return response.data.Items; 
        }); 
    } 
    

  1. var new_items = ajaxcall.getjson() Zeile gespeichert nicht die von getjson Aufruf zurückgegebenen Daten, wird es nicht definierten Wert haben als zur Zeit zu bekommen. Nach Abschluss der Änderung wird new_items Versprechen Versprechen von ajaxcall.getjson halten. Danach verwenden Sie $q.when, um das Versprechen zu behalten, aufgelöst zu werden & überprüfen Sie für Daten innerhalb seiner .then Funktion.

    customize_data = $interval(function() { //loops indefintely, new_items=undefined, why? 
        $q.when(new_items).then(function(res) { 
        if (customizeData) { 
         //Do Logic 
        } 
        }) 
    }, 200); 
    

Side Hinweis: Sie Problem mit diesem Code könnte Gesicht, wie Sie für jedes Intervall 200ms Zeit hatte. Dies kann mehrere Ajax-Aufrufe machen, bevor der letzte Aufruf abgeschlossen wird (was ein unerwartetes Verhalten wäre). Um resolve solche Frage könnte man $interval.cancel(customize_data); //once desired interval work has done

+0

Danke für die Antwort. Was ist Ihrer Meinung nach der beste Ansatz? Jemand hat mir geantwortet, dass ich statt eines Service eine Fabrik benutze. Was meinst du? Über die Randnotiz: eigentlich habe ich '$ interval.cancel' in dem Beispiel gelöscht, weil ich nicht weiß, wo ich es hinstellen soll. Direkt unter "$ interval"? Ich denke nicht, dass es sicher ist. Oder meinst du in 'if (customizeData)'? – FrancescoN

+0

Ok, es funktioniert, indem man '$ interval.cancel' in' $ interval' setzt – FrancescoN

0

Wenn Sie die Rückkehrdaten erhalten möchten, würden Sie eine Fabrik anstelle des Services schreiben!

Code:

myApp.factory('ajaxcall', ['$http', function($http) { 
    return { 
    getjson : function() { 

     $http.get("http://localhost:3000/one") 
      .then(function(response) { 

      console.log(response.data.Items); //data logged correctly 
      return response.data.Items; 
     }); 
    } 
} 
}]) 
+0

ich es versuchen würde, aber ich habe die Service-Muster auf w3schools gelernt. Bitte werfen Sie einen Blick auf den Abschnitt "Erstellen Sie Ihre eigenen Service". http://www.w3schools.com/angular/angular_services.asp Warum sollte es in meinem Fall nicht funktionieren? – FrancescoN

0

Sie mißbrauchen die promise von Ihrem asynchronen Aufruf zurückgegeben. Hier ist, was Sie in Ihrem Controller tun müssen, um die Daten zu ändern:

ajaxcall.getjson() 
.then(function(new_items) { 
    // customize data 

    // this part should go here as well 
    for(var i=0; i<new_items.length; i++) { 
     $scope.items.push(new_items[i]); 
    } 
}); 

Keine Notwendigkeit intervals oder timeouts zu verwenden. Achten Sie darauf, ajaxcall.getjson() tut NICHT geben Sie Ihre Daten zurück, es gibt das Versprechen gelöst mit Ihren Artikeln.

Lesen Sie über die promises in eckigen.

0

Verwendung Versprechen, wenn Ihre Herstellung http von Service-Anrufe

myApp.service('ajaxcall', ['$http', '$q', function($http, $q) { 
    this.getjson = function() { 
     var q = $q.defer(); 
     $http.get("http://localhost:3000/one") 
     .success(function(data) { 
      console.log(data); //data logged correctly 
      q.resolve(data); 
     }) 
     .error(function(err) { 
     q.reject(err); 
     }); 
     return q.promise; 
    } 
    }]); 

Änderungen in der Steuerung für Versprechen warten auf

ajaxcall.getjson() 
.then(function(data){ 
    console.log(data); 
});