Exemplo RESTful do recurso AngularJS $

145

Gostaria de usar $ resource para chamar meu serviço da web RESTful (no qual ainda estou trabalhando), mas gostaria de descobrir se o meu script AngularJS está correto primeiro.

O DTO todo tem: {id, order, content, done}

:cmdé para que eu possa ligar api/1/todo/resetpara limpar a tabela de tarefas no banco de dados.

Aqui está o código com o comentário do meu entendimento:

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

Uma coisa em particular que não tenho certeza é o método PATCH, não quero atualizar tudo, posso atualizar apenas um campo? Estou construindo esse pedaço de código corretamente?

Tom
fonte
2
Parece que você está usando $ resource como um serviço básico de $ http. $ resource é mais para obter um objeto de uma fonte de dados RESTful, manipulá-lo e enviá-lo de volta obj.save(). Você pode fazer o que está tentando fazer com uma implementação básica de $ http.
Ben Lesh
4
@blesh, por que ele não deve usar $ resource quando deseja se comunicar com seu serviço web RESTful? Como você disse, não é exatamente esse o objetivo?
precisa saber é o seguinte
Ele procura por mim, mas eu definiria o recurso $ como um serviço e o injetaria. Isso permite reutilizá-lo facilmente em outro lugar mais tarde, se necessário.
precisa saber é o seguinte
4
@ Fred Bem, ele pode usar $ resource como $ http se ele quiser . Mas não é assim que deveria ser usado.
precisa
3
Bem, não é realmente um "problema", por assim dizer. É mais que ele não está aproveitando a API RESTful e todas as coisas que $ resource pode fazer por você imediatamente.
Ben Lesh 28/02

Respostas:

211

O recurso $ foi criado para recuperar dados de um terminal, manipulá-los e enviá-los de volta. Você tem um pouco disso, mas não está realmente aproveitando o que foi feito para fazer.

É bom ter métodos personalizados em seu recurso, mas você não quer perder os recursos interessantes que acompanham o OOTB.

Edição : Eu não acho que expliquei isso bem o suficiente originalmente, mas $resourcefaz algumas coisas divertidas com retornos. Todo.get()e Todo.query()ambos retornam o objeto de recurso e o passam para o retorno de chamada para quando a obtenção for concluída. Ele faz algumas coisas sofisticadas com promessas nos bastidores, o que significa que você pode ligar $save()antes que o get()retorno de chamada realmente seja acionado, e vai esperar. Provavelmente, é melhor lidar apenas com seu recurso dentro de uma promessa then()ou do método de retorno de chamada.

Uso padrão

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

Da mesma forma, no caso do que você postou no OP, você pode obter um objeto de recurso e, em seguida, chamar qualquer uma de suas funções personalizadas (teoricamente):

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

No entanto, eu experimentava a implementação do OOTB antes de criar o meu. E se você achar que não está usando nenhum dos recursos padrão $resource, provavelmente deve estar usando $httpsozinho.

Atualização: Angular 1.2 e promessas

A partir do Angular 1.2, os recursos suportam promessas. Mas eles não mudaram o resto do comportamento.

Para aproveitar as promessas $resource, você precisa usar a $promisepropriedade no valor retornado.

Exemplo usando promessas

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

Lembre-se de que a $promisepropriedade é uma propriedade com os mesmos valores que estava retornando acima. Então você pode ficar estranho:

Estes são equivalentes

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;
});
Ben Lesh
fonte
1
Acho que refino minha declaração da seguinte maneira: se você não estiver usando nenhum recurso OOTB de $ resource, estará ocupando memória com referências de objeto e função que não precisa. Vai doer alguma coisa? Provavelmente não. Mas pode ser mais eficiente usar apenas $ http se você estiver executando operações CRUD padrão e não aproveitando os recursos $ neato.
Ben Lesh
5
Blesh, existem documentos que abordam a funcionalidade OOTB? Os documentos angulares são confusos.
Erichrusch
9
Infelizmente, não há, realmente. Eu só estou pesquisando a fonte deles no GitHub.
Ben Lesh
2
Não Todo.get({id: 123});retorna uma promessa e não um objeto reto?
Ingó Vals
1
Talvez você possa me ajudar com minha pergunta: stackoverflow.com/questions/30405569/… .
AJ_83
0

você pode apenas fazer $scope.todo = Todo.get({ id: 123 }). .get()e .query()em um Recurso, retorne um objeto imediatamente e preencha-o com o resultado da promessa posteriormente (para atualizar seu modelo). É não uma promessa típico que é por isso que você precisa para usar um callback ou a propriedade $ promessa se você tem algum código especial que você quer executada após a chamada. Mas não há necessidade de atribuí-lo ao seu escopo em um retorno de chamada se você estiver usando apenas no modelo.

William B
fonte