AngularJS $ resource RESTful example

145

Saya ingin menggunakan $ resource untuk memanggil layanan web RESTful saya, (yang masih saya kerjakan) tetapi saya ingin mencari tahu apakah saya memperbaiki skrip AngularJS saya terlebih dahulu.

ToTO DTO memiliki: {id, order, content, done}

:cmdjadi saya bisa menelepon api/1/todo/resetuntuk menghapus tabel todo dalam database.

Berikut adalah kode dengan komentar pengertian saya:

function TodoService($resource) {
    var src = $resource('api/1/todo/:id:cmd',
              {id: "@id", cmd: "@cmd"}, //parameters default
              {
                ListTodos: { method: "GET", params: {} },
                GetTodo: { method: "GET", params: { id: 0 } },                            
                CreateTodo: { method: "POST", params: { content: "", order: 0, done: false } },
                UpdateTodo: { method: "PATCH", params: { /*...*/ } },
                DeleteTodo: { method: "DELETE", params: { id: 0 } },
                ResetTodos: { method: "GET", params: { cmd: "reset" } },
              });

    //Usage:

    //GET without ID
    //it calls -> api/1/todo
    src.ListTodos();

    //GET with ID
    //it calls -> api/1/todo/4
    src.GetTodo({ id: 4 });

    //POST with content, order, done
    //it calls -> api/1/todo
    src.CreateTodo({ content: "learn Javascript", order: 1, done: false });

    //UPDATE content only
    //it calls -> api/1/todo/5
    src.UpdateTodo({ id: 5, content: "learn AngularJS" }); 

    //UPDATE done only
    //it calls -> api/1/todo/5
    src.UpdateTodo({ id: 5, done: true });

    //RESET with cmd
    //it calls -> api/1/todo/reset
    src.ResetTodos();
}

Satu hal khusus yang saya tidak yakin adalah metode PATCH, saya tidak ingin memperbarui semuanya, dapatkah saya memperbarui hanya satu bidang? Apakah saya membuat potongan kode ini dengan benar?

Tom
sumber
2
Sepertinya Anda menggunakan $ resource sebagai layanan dasar $ http. $ resource lebih untuk mendapatkan objek dari sumber data RESTful, memanipulasinya, lalu mengirimnya kembali obj.save(). Anda dapat melakukan apa yang Anda coba lakukan dengan implementasi $ http dasar.
Ben Lesh
4
@blesh mengapa dia tidak menggunakan $ resource ketika dia ingin berkomunikasi dengan layanan web RESTful-nya? Seperti yang Anda katakan, bukankah itu tujuan sebenarnya?
F Lekschas
Itu terlihat bagi saya tetapi saya akan mendefinisikan sumber daya $ sebagai layanan dan menyuntikkannya. Ini memungkinkan Anda untuk dengan mudah menggunakannya kembali di tempat lain nanti, jika perlu.
F Lekschas
4
@Flek Yah, dia bisa menggunakan $ resource seperti $ http jika dia mau . Tapi itu tidak benar-benar bagaimana itu dimaksudkan untuk digunakan.
Ben Lesh
3
Yah, itu sebenarnya bukan "masalah", kata orang. Lebih dari itu, dia tidak memanfaatkan api RESTful dan semua hal yang bisa dilakukan $ resource untuk kamu di luar kotak.
Ben Lesh

Jawaban:

211

$ resource dimaksudkan untuk mengambil data dari titik akhir, memanipulasinya dan mengirimkannya kembali. Anda punya beberapa di sana, tetapi Anda tidak benar-benar memanfaatkan itu untuk apa yang harus dilakukan.

Anda boleh memiliki metode khusus pada sumber daya Anda, tetapi Anda tidak ingin ketinggalan fitur keren yang ada pada OOTB.

EDIT : Saya tidak berpikir saya menjelaskan ini dengan cukup baik pada awalnya, tetapi $resourcemelakukan beberapa hal yang funky dengan pengembalian. Todo.get()dan Todo.query()keduanya mengembalikan objek sumber daya, dan meneruskannya ke dalam panggilan balik untuk saat mendapatkan selesai. Itu melakukan beberapa hal mewah dengan janji di balik layar yang berarti Anda dapat menelepon $save()sebelum get()panggilan balik benar-benar menyala, dan itu akan menunggu. Mungkin yang terbaik adalah hanya berurusan dengan sumber daya Anda di dalam janji then()atau metode panggilan balik.

Penggunaan standar

var Todo = $resource('/api/1/todo/:id');

//create a todo
var todo1 = new Todo();
todo1.foo = 'bar';
todo1.something = 123;
todo1.$save();

//get and update a todo
var todo2 = Todo.get({id: 123});
todo2.foo += '!';
todo2.$save();

//which is basically the same as...
Todo.get({id: 123}, function(todo) {
   todo.foo += '!';
   todo.$save();
});

//get a list of todos
Todo.query(function(todos) {
  //do something with todos
  angular.forEach(todos, function(todo) {
     todo.foo += ' something';
     todo.$save();
  });
});

//delete a todo
Todo.$delete({id: 123});

Demikian juga, dalam hal apa yang Anda posting di OP, Anda bisa mendapatkan objek sumber daya dan kemudian memanggil salah satu fungsi kustom Anda di atasnya (secara teoritis):

var something = src.GetTodo({id: 123});
something.foo = 'hi there';
something.UpdateTodo();

Saya akan bereksperimen dengan implementasi OOTB sebelum saya pergi dan menemukan sendiri saya. Dan jika Anda menemukan Anda tidak menggunakan salah satu fitur default $resource, Anda mungkin harus menggunakan $httpitu sendiri.

Pembaruan: Angular 1.2 dan Janji

Pada Angular 1.2, sumber daya mendukung janji. Tetapi mereka tidak mengubah perilaku lainnya.

Untuk memanfaatkan janji $resource, Anda perlu menggunakan $promiseproperti pada nilai yang dikembalikan.

Contoh menggunakan janji

var Todo = $resource('/api/1/todo/:id');

Todo.get({id: 123}).$promise.then(function(todo) {
   // success
   $scope.todos = todos;
}, function(errResponse) {
   // fail
});

Todo.query().$promise.then(function(todos) {
   // success
   $scope.todos = todos;
}, function(errResponse) {
   // fail
});

Perlu diingat bahwa $promiseproperti adalah properti dengan nilai yang sama dengan yang dikembalikan di atas. Jadi Anda bisa menjadi aneh:

Ini setara

var todo = Todo.get({id: 123}, function() {
   $scope.todo = todo;
});

Todo.get({id: 123}, function(todo) {
   $scope.todo = todo;
});

Todo.get({id: 123}).$promise.then(function(todo) {
   $scope.todo = todo;
});

var todo = Todo.get({id: 123});
todo.$promise.then(function() {
   $scope.todo = todo;
});
Ben Lesh
sumber
1
Kurasa aku akan memperbaiki pernyataan saya seperti: Jika Anda tidak menggunakan setiap fitur OOTB dari $ sumber daya, maka Anda hanya mengambil memori dengan objek dan fungsi referensi Anda tidak perlu. Apakah akan menyakiti apa pun? Mungkin tidak. Tetapi mungkin lebih efisien untuk hanya menggunakan $ http jika Anda hanya melakukan operasi CRUD standar dan tidak memanfaatkan fitur sumber daya $ neato.
Ben Lesh
5
Blesh, apakah ada dokumen yang membahas fungsi OOTB? Dokumen sudut membingungkan.
erichrusch
9
Sayangnya, tidak ada. Saya baru saja menggali sumber mereka di GitHub.
Ben Lesh
2
Tidak Todo.get({id: 123});mengembalikan janji dan bukan objek langsung?
Ingó Vals
1
Mungkin Anda dapat membantu saya dengan pertanyaan saya: stackoverflow.com/questions/30405569/… .
AJ_83
0

Anda bisa melakukannya $scope.todo = Todo.get({ id: 123 }). .get()dan .query()pada Resource, segera kembalikan objek dan isi dengan hasil dari janji nanti (untuk memperbarui template Anda). Ini bukan janji yang khas yang mengapa Anda harus menggunakan callback atau properti $ janji jika Anda memiliki beberapa kode khusus yang ingin dieksekusi setelah panggilan. Tetapi tidak perlu untuk menetapkannya ke lingkup Anda dalam panggilan balik jika Anda hanya menggunakannya dalam template.

William B
sumber