2013-06-16 13 views
19

Obecnie pracuję nad aplikacją REST + AngularJS.Obietnica w sprawie akcji oszczędzania zasobów AngularJS

Mam mały problem dotyczący obietnic dotyczących akcji oszczędzania zasobów.

Moje fabryczne:

App.factory('Course', function($resource) { 
    var course = $resource('/AppServer/admin/courses/:courseId', {}, {}); 

    course.findAll = function() { 
     return course.query(); 
    }; 

    course.findById = function(id) { 
     return course.get({ 
      courseId : id 
     }); 

    }; 

    course.saveCourse = function(course) { 
     return course.$save(); 
    } 

    return course; 
}); 

My Kontroler:

App.controller('CourseEditController', function($scope, $routeParams, $location, Course, FlashMessage) { 
    // load course into edit form 
    $scope.course = Course.findById($routeParams.courseId); 

    // save edited course and print flash message 
    $scope.saveCourse = function() { 
     var savedCourse = Course.saveCourse($scope.course); 

     savedCourse.$then(function(httpResponse) { 
      FlashMessage.set("Die Änderungen am Kurs <i>" + savedCourse.title + "</i> wurden erfolgreich gespeichert."); 
      $location.path("/kurse/verwalten"); 
     }); 
    } 
}); 

Teraz jest problem, który pojawia się następujący wyjątek:

TypeError: Cannot call method '$then' of undefined 

Najdziwniejsze jest to, że jeśli dodaj to samo oddzwanianie do jednego z finderów (np. findById) wszystko działa dobrze. Ale zwracana wartość "return course. $ Save()" jest niezdefiniowana, w porównaniu do zwracanej wartości "return course.get ({courseId: id});" który jest "obiektem obiektu".

Potrzebuję ustawić FlashMessage, kiedy akcja zapisu została w pełni wykonana, a nie wcześniej.

Wszelkie pomysły na ten temat? Odpowiedź z mojej usługi REST jest poprawna. Zwraca zapisany obiekt.

Greets Marca

+0

dzwonisz na dobry kurs. $ Save()? Istnieje "kurs" z $ resource i ten z parametrów. 'course.saveCourse = function (course)' – Utopik

+0

Wywołuję ten z params. Czy to źle? A może drugi (z zasobu) wiedział, co zaoszczędzić? – mooonli

+0

Witam, to jest całkowicie niezwiązane z pytaniem, ale tylko zastanawiam się, której biblioteki FlashMessage używasz. Czy wysyła komunikat ostrzegawczy, nawet gdy stan się zmienił? Usunie ten komentarz później. – Hussain

Odpowiedz

3

Jeśli spojrzeć na kątowym dokumentacji na resource wspomina

ważne jest, aby uświadomić sobie, że powołując się na $ zasobów metodę obiektu natychmiast zwraca pusty odniesienia (obiekt lub tablicę zależności na isArray). Po zwróceniu danych z serwera istniejące odwołanie jest wypełniane rzeczywistymi danymi.

To może bardzo dobrze oznaczać, że twoje wezwanie do zapisu $ zwróci puste odniesienie. Również then nie jest dostępny w Resource api przed Angular 1.2, ponieważ zasoby nie są oparte na promise.

Należy zmienić wywołanie metody saveCourse, aby zaakceptować parametr funkcji dla osiągnięcia sukcesu i wykonać niezbędne działanie.

42

Istnieją dwa nieznacznie różne API, jeden do pracy z instancją zasobów i - w braku lepszych słów - bardziej ogólna wersja. Główną różnicą bardzo dobrym zastosowanie $ metod -prefixed (get vs $get)

W $ metody -prefixed w ngResource/resource.js. prosi o połączenie i zwraca obietnicę bezpośrednio.

AFAIK zanim zasób zostanie dostarczony, możesz uzyskać dostęp do zasobów tylko z normalnym get.

var promise = Resource.get().$promise; 

promise.then(function(res) { console.log("success: ", res); }); 
promise.catch(function(res) { console.log("error: ", res); }); 

Z zasobu instanciated $ METODY -prefixed są dostępne:

var res = new Resource({foo: "bar"}); 

res.$save() 
    .then(function(res) { console.log("authenticated") }) 
    .catch(function(req) { console.log("error saving obj"); }) 
    .finally(function() { console.log("always called") }); 
+0

Nie jestem pewien, co robię źle, ale jakakolwiek kombinacja save, $ save, then i $ wtedy nie działa i powoduje błąd. Używam 1.0.8 Czy jesteś pewien, że to powinno działać w ten sposób? – HMR

+7

to 'Resource. $ Get()' tak samo jak 'Resource.get(). $ Promise'? – Magne

1

To dla angularjs 1.0.8

W mojej służbie Mam następujący:

angular.module('dataProvider', []). 
    factory('dataProvider', ['$resource','$q',function($resource,$q) { 
//.... 
var Student = $resource('/app/student/:studentid', 
    {studentid:'@id'} 
); 
    return { 
     newStudent:function(student){ 
     var deferred = $q.defer(); 
     var s = new Student({name:student.name,age:parseInt(student.age)}); 
     s.$save(null,function(student){ 
      deferred.resolve(student); 
     }); 
     return deferred.promise; 
     } 
    }; 
}]); 

W moim kontrolera:

$scope.createStudent=function(){ 
    dataProvider.newStudent($scope.newStudent).then(
    function(data){ 
     $scope.students.push(data); 
    }); 
}; 
+1

'$ save' zwraca obiekt z obiecującymi metodami. Możesz uniknąć tworzenia dodatkowego obiektu odroczonego, pisząc 'return s. $ Save();'. – jbielick

+0

@jbielick To dawno temu, myślę, że dodałem ten kod, aby zwrócić obietnicę, ponieważ 1.0.8 nie. https://github.com/angular/code.angularjs.org/blob/master/1.0.8/angular-resource.js (linia 420) w porównaniu do https://github.com/angular/code.angularjs.org /blob/master/1.2.9/angular-resource.js (linia 574) – HMR

0

dodałem metodę kontroler włączyć do zasobu mają obietnicę, gdy wykonuje operacje CRUD.

Metoda jest następująca:

function doCrudOpWithPromise(resourceInstance, crudOpName){ 
      var def=$q.defer() 
      resourceInstance['$'+crudOpName](function(res){def.resolve(res)}, function(err){def.reject(err)}) 
      return def.promise 
} 

Przykładem jest inwokacja:

var t=new MyResource() 
doCrudOpWithPromise(t,'save').then(...) 
0

To późno responde ale można mieć callabck na $ uratować ...

var savedCourse = Course.saveCourse($scope.course); 

savedCourse.$save(function(savedCourse, putResponseHeaders) { 
    FlashMessage.set("Die Änderungen am Kurs <i>" + savedCourse.title + "</i> wurden erfolgreich gespeichert."); 
    $location.path("/kurse/verwalten"); 
}); 
Powiązane problemy