AngularJS $ resource Ví dụ RESTful


145

Tôi muốn sử dụng $ resource để gọi dịch vụ web RESTful của mình (mà tôi vẫn đang làm việc) nhưng tôi muốn tìm hiểu xem liệu tôi có sửa tập lệnh AngularJS của mình trước không.

Việc cần làm DTO có: {id, order, content, done}

:cmdlà vì vậy tôi có thể gọi api/1/todo/resetđể xóa bảng việc cần làm trong cơ sở dữ liệu.

Đây là đoạn mã với nhận xét về sự hiểu biết của tôi:

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();
}

Một điều đặc biệt tôi không chắc chắn là phương pháp PATCH, tôi không muốn cập nhật mọi thứ, tôi có thể cập nhật chỉ một lĩnh vực không? Tôi có đang xây dựng đoạn mã này một cách chính xác không?


2
Có vẻ như bạn đang sử dụng $ resource như một dịch vụ $ http cơ bản. $ resource dùng nhiều hơn để nhận một đối tượng từ nguồn dữ liệu RESTful, thao tác với nó, sau đó gửi lại obj.save(). Bạn có thể làm những gì bạn đang cố gắng thực hiện với triển khai $ http cơ bản.
Ben Lesh

4
@bledh tại sao anh ta không nên sử dụng $ resource khi anh ta muốn giao tiếp với dịch vụ web RESTful của mình? Như bạn đã nói, đó không phải là mục đích chính xác của nó sao?
F Lekschas

Nó tìm tôi nhưng tôi sẽ định nghĩa tài nguyên $ là một dịch vụ và tiêm nó. Điều này cho phép bạn dễ dàng tái sử dụng nó ở một nơi khác sau này, nếu bạn cần.
F Lekschas

4
@Flek Vâng, anh ấy có thể sử dụng $ resource như $ http nếu muốn . Nhưng đó không thực sự là cách nó được sử dụng.
Ben Lesh

3
Vâng, nó không thực sự là một "vấn đề", mỗi lần nói. Thêm nữa là anh ta không tận dụng bất kỳ lợi thế nào của api RESTful và tất cả những thứ mà $ resource có thể làm cho bạn ra khỏi hộp.
Ben Lesh

Câu trả lời:


211

$ resource có nghĩa là lấy dữ liệu từ một điểm cuối, thao tác và gửi lại. Bạn đã có một số thứ trong đó, nhưng bạn không thực sự tận dụng nó cho những gì nó được tạo ra để làm.

Thật tốt khi có các phương thức tùy chỉnh trên tài nguyên của bạn, nhưng bạn không muốn bỏ lỡ các tính năng thú vị mà nó đi kèm với OOTB.

EDIT : Tôi không nghĩ rằng tôi đã giải thích điều này đủ tốt ban đầu, nhưng $resourcethực hiện một số thứ thú vị với lợi nhuận. Todo.get()Todo.query()cả hai trả về đối tượng tài nguyên, chuyển nó vào hàm gọi lại khi get hoàn thành. Nó thực hiện một số nội dung thú vị với những lời hứa đằng sau hậu trường có nghĩa là bạn có thể gọi $save()trước khi cuộc get()gọi lại thực sự bắt đầu và nó sẽ chờ. Có lẽ tốt nhất chỉ là xử lý tài nguyên của bạn bên trong một lời hứa then()hoặc phương thức gọi lại.

Tiêu chuẩn sử dụng

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});

Tương tự, trong trường hợp những gì bạn đã đăng trong OP, bạn có thể lấy một đối tượng tài nguyên và sau đó gọi bất kỳ chức năng tùy chỉnh nào của bạn trên đó (về mặt lý thuyết):

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

Tôi đã thử nghiệm triển khai OOTB trước khi tôi đi và phát minh ra của riêng tôi. Và nếu bạn thấy bạn không sử dụng bất kỳ tính năng mặc định nào $resource, có lẽ bạn chỉ nên sử dụng tính năng $httpnày.

Cập nhật: Angular 1.2 và Promise

Kể từ Angular 1.2, tài nguyên hỗ trợ hứa hẹn. Nhưng họ đã không thay đổi phần còn lại của hành vi.

Để thực hiện lời hứa với $resource, bạn cần sử dụng$promise tính trên giá trị được trả về.

Ví dụ sử dụng lời hứa

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
});

Chỉ cần nhớ rằng $promise tài sản là một tài sản trên cùng các giá trị mà nó đã trả lại ở trên. Vì vậy, bạn có thể nhận được kỳ lạ:

Đây là tương đương

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;
});

1
Tôi đoán tôi sẽ tinh chỉnh tuyên bố của mình như vậy: Nếu bạn không sử dụng bất kỳ tính năng OOTB nào của $ resource, thì bạn chỉ chiếm bộ nhớ với các tham chiếu đối tượng và chức năng mà bạn không cần. Nó sẽ làm tổn thương bất cứ điều gì? Chắc là không. Nhưng có thể hiệu quả hơn nếu chỉ sử dụng $ http nếu bạn chỉ thực hiện các thao tác CRUD tiêu chuẩn và không tận dụng các tính năng gọn gàng của tài nguyên $.
Ben Lesh

5
Xác thịt, có tài liệu nào đi qua chức năng OOTB không? Các tài liệu góc cạnh là khó hiểu.
erichrusch

9
Đáng buồn thay, thực sự không có. Tôi vừa mới đào qua nguồn của họ trên GitHub.
Ben Lesh

2
Không Todo.get({id: 123});trả lại một lời hứa và không phải là một đối tượng thẳng lên?
Ingó Vals

1
Có lẽ bạn có thể giúp tôi với câu hỏi của tôi: stackoverflow.com/questions/30405569/ cấp .
AJ_83

0

bạn chỉ có thể làm $scope.todo = Todo.get({ id: 123 }). .get().query()trên Tài nguyên trả về một đối tượng ngay lập tức và điền vào kết quả của lời hứa sau (để cập nhật mẫu của bạn). Đây không phải là một lời hứa thông thường, đó là lý do tại sao bạn cần sử dụng thuộc tính gọi lại hoặc thuộc tính $ hứa nếu bạn có một số mã đặc biệt bạn muốn thực hiện sau cuộc gọi. Nhưng không cần gán nó cho phạm vi của bạn trong một cuộc gọi lại nếu bạn chỉ sử dụng nó trong mẫu.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.