从服务器获取数据的推荐方式

145

在AngularJS中,不使用$resource,连接服务器数据源的推荐方法是什么。

$resource存在许多限制,例如:

  1. 未使用适当的futures(译注:即使用异步请求)
  2. 不够灵活

6
自从这个问题(https://github.com/angular/angular.js/issues/415)得到解决,$resource是否仍存在不能使用合适的futures的限制?我是Angular的新手,如果问题不清楚,请见谅。编辑-此提交记录(https://github.com/angular/angular.js/commit/dba6bc73e802fdae685a9f351d3e23c7efa8568a)似乎也暗示着$resource现在可能不再有那个限制了? - Jason Sydes
1
好的,在这里回答自己的问题是合法的,可以吗?点击“提问”,这被称为“分享你的知识”。 - holms
2个回答

230

有时候在与后端通信时可能不适合使用$resource。以下示例演示如何设置类似于$resource的行为而不使用resource。

angular.module('myApp').factory('Book', function($http) {
  // Book is a class which we can use for retrieving and 
  // updating data on the server
  var Book = function(data) {
    angular.extend(this, data);
  }

  // a static method to retrieve Book by ID
  Book.get = function(id) {
    return $http.get('/Book/' + id).then(function(response) {
      return new Book(response.data);
    });
  };

  // an instance method to create a new Book
  Book.prototype.create = function() {
    var book = this;
    return $http.post('/Book/', book).then(function(response) {
      book.id = response.data.id;
      return book;
    });
  }

  return Book;
});

那么在你的控制器中,你可以这样做:

var AppController = function(Book) {
  // to create a Book
  var book = new Book();
  book.name = 'AngularJS in nutshell';
  book.create();

  // to retrieve a book
  var bookPromise = Book.get(123);
  bookPromise.then(function(b) {
    book = b;
  });
};

1
也许是一个新手问题,但如何扩展它以允许获取(get())返回不止一个响应而是多个响应? - Nate Bunney
2
@NathanBunney,你可以在循环之前编写静态get方法,遍历结果并构建一个书籍数组。 - Ben Lesh
4
@NathanBunney 的代码段翻译如下:Book.getAll = function() { return $http.get('/Book').then(function(response) { var books = []; for(var i = 0; i < response.data.length; i++){ books.push(new Book(response.data[i])); } return books; }); };意为“Book.getAll”函数,调用后会向服务器请求获取图书数据,并将返回的数据转换成一个包含多个Book对象的数组。 - Yair Nevet
2
你如何在控制器之间共享一个book或一组book - Lukas
1
这很棒(显然因为Misko创建了这个框架),但我正在努力弄清楚如何使其可重用。如果我只想实现CRUD函数一次,然后在需要仅具有urlBase参数的子工厂/服务中继承它们的功能(最好存储在原型上,以便每个实例不需要新的urlBase副本),我该怎么做? - Dean Stamler
显示剩余6条评论

26
我建议你使用$resource
在AngularJS的下一个版本中,它可能会支持(url override)。 然后你就可以像这样编写代码:
// need to register as a serviceName
$resource('/user/:userId', {userId:'@id'}, {
    'customActionName':    {
        url:'/user/someURI'
        method:'GET',
        params: {
            param1: '....',
            param2: '....',
        }
    },
     ....
});

在控制器范围内,可以像这样处理返回回调。
// ctrl scope
serviceName.customActionName ({
    paramName:'param',
    ...
}, 
function (resp) {
    //handle return callback
}, 
function (error) {
    //handler error callback
});

也许你可以处理更高抽象层次的代码。

2
Angular.js 的当前版本支持在 $resource 模块中进行 URL 覆盖。 - thanksnote
17
哈哈,你正在向这个框架的实际创造者推荐如何做某事 :P - HeberLZ
11
天啊!我感到非常羞愧。 - thanksnote

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接