Пример RESTful для AngularJS $

Я хотел бы использовать $resource для вызова моего веб-сервиса RESTful (который я все еще работаю), но я хотел бы узнать, сначала ли я получил свой AngularJS script.

Todo 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, я не хочу обновлять все, могу ли я обновить только одно поле? Правильно ли я построил этот кусок кода?

Ответ 1

$resource предназначался для извлечения данных из конечной точки, управления им и отправки его обратно. У вас есть кое-что из этого, но вы на самом деле не используете его для своих целей.

Хорошо, что у вас есть собственные методы на вашем ресурсе, но вы не хотите пропустить интересные функции, которые он предлагает с OOTB.

РЕДАКТИРОВАТЬ. Я не думаю, что я объяснил это достаточно хорошо изначально, но $resource делает некоторые фанки с возвратами. Todo.get() и Todo.query() оба возвращают объект ресурса и передают его в обратный вызов для завершения завершения. Он имеет некоторые причудливые вещи с promises за кулисами, которые означают, что вы можете вызвать $save() до того, как обратный вызов get() действительно срабатывает, и он будет ждать. Вероятно, лучше всего иметь дело с вашим ресурсом внутри обещания 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 и Promises

Как и в случае с Angular 1.2, поддержка ресурсов promises. Но они не изменили остальное поведение.

Чтобы использовать promises с помощью $resource, вам нужно использовать свойство $promise для возвращаемого значения.

Пример использования Promises

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

Ответ 2

вы можете просто сделать $scope.todo = Todo.get({ id: 123 }). .get() и .query() в ресурсе возвращают объект немедленно и заполняют его результатом обещания позже (для обновления вашего шаблона). Это не типичное обещание, поэтому вам нужно либо использовать обратный вызов, либо свойство $prom, если у вас есть специальный код, который вы хотите выполнить после вызова. Но нет необходимости присваивать его области видимости в обратном вызове, если вы используете ее только в шаблоне.