AngularJS $ resource RESTful приклад


145

Я хотів би використати $ ресурс для виклику моєї веб-служби RESTful (над якою я все ще працюю), але я хотів би дізнатися, чи спочатку я отримав правильний сценарій AngularJS.

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, я не хочу все оновлювати, чи можу я оновити лише одне поле? Я правильно будую цей фрагмент коду?


2
Схоже, ви використовуєте $ ресурс як основну послугу $ http. $ ресурс - це більше для отримання об'єкта з RESTful джерела даних, маніпулювання ним, а потім надсилання назад obj.save(). Ви можете зробити те, що намагаєтесь зробити з базовою реалізацією $ http.
Бен Леш

4
@blesh чому він не повинен використовувати $ ресурс, коли хоче спілкуватися зі своєю RESTful веб-службою? Як ви вже говорили, чи не це саме мета?
F Lekschas

Мене шукає, але я б визначив $ ресурс як послугу і ввів його. Це дозволяє вам легко повторно використовувати його в іншому місці пізніше, якщо вам потрібно.
F Lekschas

4
@Flek Добре, що він може використовувати $ ресурс, як $ http, якщо захоче . Але це не зовсім так, як це було призначено для використання.
Бен Леш

3
Ну, це насправді не "проблема", скажімо. Більше того, що він не використовує жодних переваг від RESTful api та всіх речей, які $ ресурс може зробити для вас поза коробкою.
Бен Леш

Відповіді:


211

$ ресурс мав на меті отримати дані з кінцевої точки, маніпулювати ними та відправити назад. У вас є щось із цього, але ви не дуже використовуєте це для того, що було зроблено.

Добре, щоб на вашому ресурсі були спеціальні методи, але ви не хочете пропускати класні функції, які поставляються з OOTB.

EDIT : Я не думаю, що я пояснив це досить добре спочатку, але $resourceробить якісь прикольні речі із поверненнями. Todo.get()і Todo.query()обидва повертають об'єкт ресурсу та передають його у зворотний виклик, коли завершується отримання. Це щось фантазійне, з обіцянками за лаштунками, які означають, що ви можете зателефонувати, $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});

Так само, у випадку, що ви розмістили в ОП, ви можете отримати ресурсний об'єкт, а потім викликати будь-яку зі своїх спеціальних функцій (теоретично):

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

Я б експериментував з реалізацією OOTB, перш ніж я пішов і винайшов своє. І якщо ви виявите, що не використовуєте жодної з функцій за замовчуванням $resource, ви, ймовірно, просто використовуєте $httpйого самостійно.

Оновлення: кутова 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;
});

1
Напевно, я вдосконалю своє твердження так: Якщо ви не використовуєте жодних функцій OOTB ресурсу $, то ви просто забираєте пам'ять із посиланнями на об’єкти та функції, які вам не потрібні. Чи буде щось боляче? Напевно, ні. Але може бути більш ефективним просто використовувати $ http, якщо ви просто робите стандартні операції з CRUD і не використовуєте параметри $ ресурси, не використовуючи функції.
Бен Леш

5
Blesh, чи є документи, які переходять на функціонал OOTB? Кутові документи заплутані.
erichrusch

9
На жаль, насправді немає. Я щойно копав їх джерело на GitHub.
Бен Леш

2
Не Todo.get({id: 123});повертає обіцянку і не прямий об'єкт?
Ingó Vals

1
Можливо, ви можете мені допомогти з моїм питанням: stackoverflow.com/questions/30405569/… .
AJ_83

0

можна просто зробити $scope.todo = Todo.get({ id: 123 }). .get()а .query()на Ресурс негайно поверніть об’єкт і пізніше заповніть його результатом обіцянки (оновити ваш шаблон). Це не типова обіцянка, через що вам потрібно використовувати зворотний виклик або властивість $ обещання, якщо у вас є якийсь спеціальний код, який потрібно виконати після дзвінка. Але немає необхідності призначати його до своєї області у зворотній зв'язок, якщо ви використовуєте його лише в шаблоні.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.