AngularJS $ resource RESTful示例


145

我想使用$ resource调用我的RESTful Web服务(我仍在使用它),但是我想知道我是否首先正确地使用了AngularJS脚本。

待办事项DTO具有: {id, order, content, done}

:cmd因此,我可以调用api/1/todo/reset以清除数据库中的todo表。

这是带有我的理解注释的代码:

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

我不确定的一件事是PATCH方法,我不想更新所有内容,可以仅更新一个字段吗?我是否正确构建了这段代码?


2
看来您将$ resource用作基本的$ http服务。$ resource更适用于从RESTful数据源获取对象,对其进行处理,然后使用发送回obj.save()。您可以使用基本的$ http实现来完成您想做的事情。
Ben Lesh 2012年

4
@blesh当他想与他的RESTful Web服务通信时,为什么不使用$ resource?如您所说,这不是目的吗?
F Lekschas,2012年

它在找我,但是我将$ resource定义为服务并注入它。如果需要,这使您可以在以后的其他地方轻松地重用它。
F Lekschas

4
@Flek好吧,如果愿意的话,他可以像$ http这样使用$ resource 。但这并不是真的要使用它。
Ben Lesh 2012年

3
好吧,这并不是一个真正的“问题”。更重要的是,他没有充分利用RESTful API和$ resource可以为您提供的所有功能。
Ben Lesh

Answers:


211

$ resource旨在从端点检索数据,对其进行处理并将其发送回。您已经有了其中的一些功能,但是您并没有真正利用它来完成它。

在您的资源上有自定义方法是很好的,但是您不想错过OOTB附带的很酷的功能。

编辑:我认为我本来解释得不够好,但是$resource做了一些带有回报的时髦东西。Todo.get()Todo.query()两个返回的资源对象,把它传递到回调的GET完成时。它在幕后做了一些花哨的承诺,这意味着您可以$save()get()回调实际触发之前调用,它将等待。最好只在promise then()或callback方法中处理您的资源。

标准使用

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

同样,对于在OP中发布的内容,您可以获取一个资源对象,然后在其上调用任何自定义函数(理论上):

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

在我去发明自己的OOTB之前,我曾尝试过OOTB实现。而且,如果您发现自己没有使用的任何默认功能$resource,则可能应该$http自己使用。

更新:Angular 1.2和Promises

从Angular 1.2开始,资源支持承诺。但是他们没有改变其余的行为。

$resource通过使用诺言,您需要$promise在返回值上使用属性。

使用承诺的示例

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

请记住,该$promise属性是具有与上面返回的值相同的属性。所以你会变得很奇怪:

这些是等效的

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
我想我应该像这样来完善我的陈述:如果您不使用$ resource的任何 OOTB功能,那么您只是占用不需要的对象和函数引用的内存。它会伤害任何东西吗?可能不是。但是,如果您只是在进行标准的CRUD操作,而没有利用$ resources neato功能,则仅使用$ http可能会更有效率。
Ben Lesh 2012年

5
亲爱的,有没有涉及OOTB功能的文档?角度文档令人困惑。
erichrusch

9
可悲的是,实际上没有。我只是在GitHub上挖掘他们的源代码。
本·莱什

2
Todo.get({id: 123});返回承诺而不是直截了当的对象吗?
INGO丘壑

1
也许您可以为我的问题提供帮助:stackoverflow.com/questions/30405569/…
AJ_83

0

你可以做$scope.todo = Todo.get({ id: 123 }).get()然后.query()在Resource上立即返回一个对象,并在以后用promise的结果填充它(以更新模板)。它的不是一个典型的承诺,这就是为什么如果您要在调用后执行一些特殊代码,则需要使用回调或$ promise属性。但是,如果仅在模板中使用它,则无需在回调中将其分配给您的作用域。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.