答案 0 :(得分:11)
创建新资源类型时,可以为其提供可执行的操作列表。默认情况下,这些是get
,save
,query
,delete
和remove
(我认为删除只是删除的别名)。您可以添加自己的,如文档中所述。
关于class vs instance的事情是关于它为了方便使用而做的事情。 “类操作”是指从您自己创建的资源类调用操作,有点像其他语言中的静态或共享方法。当您还没有实例时,这可用作获取,查询或保存资源实例的入口点。 get
和query
是最明显的例子。如果您有Car
资源,并且需要检索它,那么您从哪里开始?当然,使用集体诉讼,例如get
。
现在,当您的资源类检索现有实例或创建新实例时,$resource
将使用为您的资源定义的操作扩展您的实例,但前缀为$
,以便它们不要与资源上的字段发生冲突。这些是您的实例操作。实例和类之间的区别是实例是在当前实例的上下文中完成的。因此,如果你get
一个实例,然后在该实例上调用$save
或$delete
,它将专门保存或删除该实例。实例操作只是为了方便起见。
所以它们几乎相同,区别在于它们的使用环境。
function($resource) {
// first let's define a new resource for car, where all cars have an id field
// calling $resource will create a new resource class that can be used to
// create, retrieve, update, or delete instances
// this is usually done as a service and injected into controllers as needed.
var Car = $resource('/api/car/:id', {id: '@id'});
// the car class we just created has some class actions that can help you query for or get car instances
// let's create a new instance of a car and save it
var newCar = new Car({make: 'Toyota', model: 'Prius'});
// the prototype of Car includes the instance action versions of the actions defined for the resource. below, $save is your instance action
newCar.$save(); // server will respond with the object after it's saved, so we can now access the id. let's say the id it returned is 24, we'll reference this value later.
// now, let's imagine some time later we want to retrieve the car and update it
// Car.get is a class action that requests the resource from the server, parses the JSON into an object, and merges it with the Car instance prototype so you have your instance actions
// let's get the car we created previously.
// remember, this is done asynchronously, so we will do our work in a success handler that we provide to get
Car.get({id: 24}, function(myCar) {
// let's update the car now that we have it. let's set the year of the model and the color
myCar.year = 2004;
myCar.color = 'white';
// now, let's save our changes by calling the instance action $save
myCar.$save();
});
// now, let's query for all cars and get an array back
// query is a class function that expects an array of your resource to be returned
Car.query(function(cars) {
// trivial example, we're just going to enumerate the cars we found and log some info about them
for(var i = 0; i < cars.length; i++)
console.log('Found ' + cars[0].color + ' ' cars[0].year + ' ' + cars[0].make + ' ' + cars[0].model);
});
// ok, let's delete the car we created earlier. use the class action delete
Car.delete({id: 24});
}
从技术上讲,您可以将任何操作调用为类或实例,但很明显,有些操作可能很难用作实例操作,反之亦然。例如,虽然您在技术上可以使用query
作为实例操作,但在实践中您不会这样做,因为它是额外的工作而且很尴尬(您必须执行new Car().$query()
。这很愚蠢。{ {1}}更容易,更有意义)。因此,上面示例中的用法表示您的正常使用情况。
更新
Car.query()
vs save
$save
与$save
类似,但它假设您要在保存期间提交的数据本身,因为save
是实例操作。它特别有用,因为在收到响应后,它将使用HTTP端点返回的对象更新自身。因此,如果您的服务使用服务器端填充的一些其他值(例如ID)保存对象,然后将对象作为JSON发回,$save
将使用返回的JSON对象更新实例。
$save
您可以使用类方法执行类似的操作,但它很笨拙,特别是如果您正在处理它时控制器中的其他代码需要引用汽车
var car = new Car({make: 'Toyota', model: 'Prius'});
// at this point there is no id property, only make and model
car.$save(function() {
// angular is async, so we need a success handler to continue the explanation
// assuming your server assigned an ID and sent the resulting object back as JSON, you can now access id off the original object
console.log(car.id); // has a value now
});
或
Car.save({make: 'Toyota', model: 'Prius'}, function(car) {
// ok, we have an ID now
console.log(car.id);
});
var car = new Car({...});
Car.save(car, function(newCar) {
car = newCar; // wut? that's awkward
});
可能在您快速保存小型对象或执行某种“火上浇油”的情况下非常有用。无论如何,我自己很少使用save
。