2016-06-30 2 views
0

Ich kann einfach nicht meinen Kopf Versprechen bekommen. Konzeptionell bekomme ich, was sie tun Ich weiß nur nicht, wie man es schreibt (oder zumindest debuggen).eckige Versprechen und Service

MyController.js

(function() { 
    angular.module('WizmoApp').controller('StoreController', storeController); 
    storeController.$inject = ['$scope', '$http', '$q', '$window', 'MyService', 'toastr']; 
    function storeController($scope, $http, $q, $window, MyService, toastr) { 

    StoreService.getStores().then(
     function(response) { 
      console.log(response); 
     }, 
     function(response) { 
      toastr.error(response); 
     }); 
    } 
})(); 

Soweit ich sagen kann, ist, dass das Format für ein Versprechen.

MyService.js

(function() { 
    angular 
    .module('WizmoApp') 
    .service('StoreService', storeService); 
    storeService.$inject = ['$http', '$q', 'ngAuthSettings']; 

    function storeService($http, $q, ngAuthSettings) { 

     this.getStores = function() { 
      $.getJSON('Content/data/Stores.json', function (json) { 
          return json; 
      }); 
    }; 
})(); 

Der Fehler, den ich bekommen ist

StoreService.getStores (...). Dann ist keine Funktion

+1

Verwenden Sie $ http, um HTTP-Anfragen zu stellen und Versprechen abzugeben. Nicht JQuery. Lesen Sie http://blog.ninja-squad.com/2015/05/28/angularjs-promises/ –

+0

Der Grund, warum ich einen Service verwende, ist, dass ich zwischen API und lokalem json umdrehen kann. Die Verwendung von $ http in meinem Controller erzwingt eine Auswahl, die ich offen lassen möchte. – DaveC426913

+1

Sie können $ http in Ihrem Dienst verwenden, ich glaube, was JB Nizet bezieht, ist Ihre Verwendung von '$ .getJSON' dort ... – seanhodges

Antwort

1

Sie müssen das Versprechen Resolver zurück, so dass Sie die .then aufrufen kann() Funktion auf sie. Zum Beispiel:

this.getStores = function() { 
    return $q(function(resolve, reject) { 
    $.getJSON('Content/data/Stores.json', function (json) { 
     resolve(json); 
    }); 
    }); 
} 

Oder die ältere Commonjs Notation:

this.getStores = function() { 
    var deferred = $q.defer(); 
    $.getJSON('Content/data/Stores.json', function (json) { 
     deferred.resolve(json); 
    }); 
    return deferred.promise; 
} 

Denken Sie daran, $ q in Ihre StoreService zu injizieren. Sehen Sie hier für weitere Informationen: https://docs.angularjs.org/api/ng/service/$q

+0

OK, das scheint zu funktionieren, obwohl ich denke, dass ich es immer noch nicht richtig habe, weil ich jetzt ein verschachteltes Versprechen habe.Ich werde den Kontext dessen zeigen, was ich mit dem Service mache (was ich vielleicht vorher hätte tun sollen, aber es hätte Dinge kompliziert gemacht). – DaveC426913

1

Ohne in Plunker noch zu testen , Ihr Dienst wird als "MyService" und nicht als "StoreService" eingegeben. Daher sollte es so aussehen:

storeController. $ Inject = [$ scope, $ http, $ q, $ window, StoreService, toastr]; Funktion storeController ($ Umfang, $ http, $ q, $ Fenster, StoreService, toastr) {

StoreService.getStores().then(
+0

Ja. Es heißt eigentlich StoreService. – DaveC426913

+0

in Ihrem $ inject haben Sie MyService, sollte es StoreService sein: storeController. $ Inject ... Ich aktualisierte meine Antwort. Lass es mich wissen – Gregori

+0

Ja, das ist nicht das Problem. – DaveC426913

0

Ich dachte nicht, dass dies relevant war - ich dachte, es würde nur meine Frage komplizieren, aber es scheint eng zu sein. Der Zweck des Dienstes besteht darin, dass ich zwischen "gespeicherten" json-Daten und Live-api-Daten hin und her blättern kann.

Siehe die Datasource-Variable in dem Schalter verwendet:

storeController.js

StoreService.getStores().then(function(response) { 
    vm.stores = response.data; 
}, function(response) { 
    toastr.error(response); 
}); 

storeService.js

(function() { 
    'use strict'; 

    angular 
     .module('WizmoApp') 
     .service('StoreService', storeService); 

    storeService.$inject = ['$http', '$q', 'ngAuthSettings']; 

    function storeService($http, $q, ngAuthSettings) { 

     var dataSource = 'api';// local or api 

     this.getStores = function() { 

      return $q (function(resolve, reject) { 
       switch (dataSource) { 
        case 'api'://staging - live api data 
         $http({ 
          method: 'get', 
          url: serviceBase + 'api/Stores' 
         }).then(function(results) { 
          resolve(results.data); 
         }); 
         break; 

        default: // dev - local json 
         $.getJSON('Content/data/Stores.json', function (json) { 
          resolve(json); 
         }); 
       } 
      }); 
     }; 

So, jetzt habe ich ein Versprechen in der anderen verschachtelt bekam . Es scheint zu funktionieren, ich bin mir nur nicht sicher, ob es effizient ist.