【问题标题】:AngularJS $resource RESTful exampleAngularJS $resource RESTful 示例
【发布时间】:2012-10-27 12:26:46
【问题描述】:

我想使用 $resource 来调用我的 RESTful Web 服务(我仍在努力),但我想先看看我的 AngularJS 脚本是否正确。

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

:cmd 这样我就可以调用api/1/todo/reset 来清除数据库中的待办事项表。

这是我理解的注释代码:

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 方法,我不想更新所有内容,我可以只更新一个字段吗?我是否正确构建了这段代码?

【问题讨论】:

  • 看起来您正在使用 $resource 作为基本的 $http 服务。 $resource 更多的是用于从 RESTful 数据源获取对象,对其进行操作,然后使用 obj.save() 将其发送回。您可以使用基本的 $http 实现来做您想做的事情。
  • @blesh 当他想与他的 RESTful web 服务通信时,为什么不应该使用 $resource 呢?正如你所说,这不正是它的目的吗?
  • 它会寻找我,但我会将 $resource 定义为服务并注入它。如果需要,这使您可以在以后轻松地在其他地方重复使用它。
  • @Flek 好吧,如果他想要,他可以像 $http 一样使用 $resource。但这并不是它的真正用途。
  • 嗯,这不是一个真正的“问题”,每个人说。更重要的是,他没有利用 RESTful api 以及 $resource 开箱即用可以为您做的所有事情。

标签: javascript rest angularjs


【解决方案1】:

$resource 旨在从端点检索数据,对其进行操作并将其发送回。你有一些其中的内容,但你并没有真正利用它来完成它的目的。

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

编辑:我认为我最初对此的解释不够好,但$resource 做了一些时髦的回报。 Todo.get()Todo.query()return 资源对象, 将其传递给 callback 以供获取完成时使用。它在幕后做了一些带有承诺的花哨的东西,这意味着你可以在get() 回调实际触发之前调用$save(),它会等待。最好只在 promise then() 或回调方法中处理您的资源。

标准使用

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 实现。如果你发现你没有使用$resource 的任何默认功能,你应该只使用$http 自己。

更新:Angular 1.2 和承诺

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

【讨论】:

  • 我想我会像这样完善我的陈述:如果您没有使用 $resource 的 any OOTB 功能,那么您只是在使用对象和您不需要的函数引用。它会伤害任何东西吗?可能不是。但是如果你只是在做标准的 CRUD 操作而不是利用 $resources 的整洁功能,那么只使用 $http 可能会更有效。
  • Blesh,有没有关于 OOTB 功能的文档?角度文档令人困惑。
  • 遗憾的是,真的没有。我一直在挖掘他们在 GitHub 上的源代码。
  • Todo.get({id: 123}); 不是返回一个承诺而不是一个直接的对象吗?
  • 也许你可以帮我解决我的问题:stackoverflow.com/questions/30405569/….
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-17
    • 1970-01-01
    • 1970-01-01
    • 2014-05-28
    • 2015-09-16
    • 2016-08-02
    • 1970-01-01
    相关资源
    最近更新 更多