Zalecany sposób pobierania danych z serwera

145

Jaki jest zalecany sposób łączenia się ze źródłami danych serwera w AngularJS bez użycia $resource.

$resourceMa wiele ograniczeń, takich jak:

  1. Nie używać właściwej przyszłości
  2. Nie jest wystarczająco elastyczny
Misko Hevery
źródło
6
Czy nadal prawdą jest, że $ zasób ma ograniczenie dotyczące nieużywania odpowiednich kontraktów terminowych, biorąc pod uwagę, że ten problem (https://github.com/angular/angular.js/issues/415) został zamknięty? (Jestem nowy w Angular, przepraszam, jeśli pytanie jest niejasne.) EDYCJA - To zatwierdzenie ( github.com/angular/angular.js/commit/… ) również wydaje się sugerować, że $ resource może już nie mieć tego ograniczenia?
Jason Sydes
1
cóż, tutaj legalne jest odpowiadanie na własne pytania .. ok? naciśnij „Zadaj pytanie”, czyli „podziel się swoją wiedzą”
holms

Odpowiedzi:

229

Istnieją przypadki, w których $ resource może nie być odpowiednia podczas komunikacji z backendem. To pokazuje, jak skonfigurować zachowanie podobne do $ resource bez używania resource.

angular.module('myApp').factory('Book', function($http) {
  // Book is a class which we can use for retrieving and 
  // updating data on the server
  var Book = function(data) {
    angular.extend(this, data);
  }

  // a static method to retrieve Book by ID
  Book.get = function(id) {
    return $http.get('/Book/' + id).then(function(response) {
      return new Book(response.data);
    });
  };

  // an instance method to create a new Book
  Book.prototype.create = function() {
    var book = this;
    return $http.post('/Book/', book).then(function(response) {
      book.id = response.data.id;
      return book;
    });
  }

  return Book;
});

Następnie wewnątrz kontrolera możesz:

var AppController = function(Book) {
  // to create a Book
  var book = new Book();
  book.name = 'AngularJS in nutshell';
  book.create();

  // to retrieve a book
  var bookPromise = Book.get(123);
  bookPromise.then(function(b) {
    book = b;
  });
};
Misko Hevery
źródło
1
Może to pytanie noob, ale jak można by to rozszerzyć, aby funkcja get () zwracała wiele odpowiedzi, a nie tylko jedną odpowiedź?
Nate Bunney
2
@NathanBunney, możesz mieć swoją statyczną metodę get powyżej, w pętli wyników i zbudować tablicę książek.
Ben Lesh
4
@NathanBunney 'Book.getAll = function () {return $ http.get (' / Book '). Then (function (response) {var books = []; for (var i = 0; i <response.data.length ; i ++) {books.push (new Book (response.data [i]));} return books;}); }; '
Yair Nevet
2
W jaki sposób udostępniłbyś bookkolekcję lub kolekcje bookmiędzy kontrolerami?
Lukas
1
To jest świetne (oczywiście od czasu, gdy Misko stworzył framework), ale staram się wymyślić, jak sprawić, by był wielokrotnego użytku. Gdybym chciał zaimplementować funkcje CRUD tylko raz, a następnie odziedziczyć ich funkcjonalność w podrzędnych fabrykach / usługach, które wymagały tylko argumentu urlBase (najlepiej przechowywanego w prototypie, aby każda instancja nie potrzebowała nowej kopii bazy url), w jaki sposób Robię to?
Dean Stamler
26

Zalecam użycie $ resource .

Może obsługiwać (nadpisywanie adresu URL) w następnej wersji Angularjs. Wtedy będziesz mógł kodować w ten sposób:

// need to register as a serviceName
$resource('/user/:userId', {userId:'@id'}, {
    'customActionName':    {
        url:'/user/someURI'
        method:'GET',
        params: {
            param1: '....',
            param2: '....',
        }
    },
     ....
});

A wywołania zwrotne zwrotne mogą być obsługiwane w zakresie ctrl w ten sposób.

// ctrl scope
serviceName.customActionName ({
    paramName:'param',
    ...
}, 
function (resp) {
    //handle return callback
}, 
function (error) {
    //handler error callback
});

Prawdopodobnie poradzisz sobie z kodem na wyższym poziomie abstrakcji.

podziękowanie
źródło
2
Obecna wersja angular.js obsługuje nadpisywanie adresu URL w module $ resource.
przypis z podziękowaniem
16
Haha, polecasz faktycznego twórcę frameworka, jak coś zrobić: P
HeberLZ
11
O MÓJ BOŻE! Tak mi wstyd.
przypis z podziękowaniem