AngularJS $ ресурс RESTful пример

145

Я бы хотел использовать $ resource для вызова моего веб-сервиса RESTful (над которым я до сих пор работаю), но я хотел бы узнать, правильно ли я сначала сделал мой скрипт 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, я не хочу обновлять все, могу ли я обновить только одно поле? Я правильно строю этот кусок кода?

Том
источник
2
Похоже, вы используете $ resource в качестве основного сервиса $ http. $ resource - это больше для получения объекта из источника данных RESTful, манипулирования им, а затем отправки его обратно obj.save(). Вы можете сделать то, что вы пытаетесь сделать с базовой реализацией $ http.
Бен Леш
4
@blesh, почему он не должен использовать $ resource, когда хочет общаться со своим веб-сервисом RESTful? Как вы сказали, не в этом ли цель?
Ф Лексчас
Он ищет меня, но я бы определил ресурс $ как сервис и внедрил его. Это позволяет вам легко использовать его в другом месте позже, если вам это нужно.
Ф Лексчас
4
@Flek Ну, он может использовать $ resource как $ http, если захочет . Но это не совсем так, как это должно было быть использовано.
Бен Леш
3
Ну, на самом деле это не «проблема», скажем так. Более того, он не пользуется API RESTful и всем тем, что $ resource может сделать для вас из коробки.
Бен Леш

Ответы:

211

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

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

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

Начиная с версии 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
Думаю, я уточню свое утверждение следующим образом: если вы не используете какие-либо OOTB-функции $ resource, тогда вы просто занимаете память ссылками на объекты и функции, которые вам не нужны. Будет ли что-нибудь больно? Возможно нет. Но может быть более эффективно просто использовать $ http, если вы просто выполняете стандартные операции CRUD и не используете функции $ resources neato.
Бен Леш
5
Блеш, есть какие-нибудь документы, которые касаются функциональности OOTB? Угловые документы сбивают с толку.
erichrusch
9
К сожалению, нет, правда. Я просто копался в их источнике на GitHub.
Бен Леш
2
Не Todo.get({id: 123});возвращает обещание, а не прямой объект?
Инго Вальс
1
Возможно, вы можете помочь мне с моим вопросом: stackoverflow.com/questions/30405569/… .
AJ_83
0

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

Уильям Б
источник