作为$resource to return array of [OO] objects如何从$ resource
正确包装新域对象实例的后续行动app.factory('NoteResource', ['$resource', function($resource) {
var res = $resource('http://okigan.apiary.io/notes/:id', null, ...);
res.newInstance = function() {
return angular.extend(new Note(), res);
};
}
NoteResource.newInstance()将返回带有标准$ save / $ update方法的对象。
答案 0 :(得分:1)
发布我的解决方案供参考:
最新演示:http://plnkr.co/edit/AVLQItPIfoLwsgDzoBdK?p=preview
解决方案的关键项是将返回的json对象包装到javascript对象中 正确 set prototype 。
var app = angular.module('plunker', ['ngResource']);
//
function Note() {
this.id = '<new id>';
this.title = '<new title>';
this.checked = false;
this.spellCheck = function() {
// imagine spellchecking logic here
this.checked = true;
};
}
app.factory('NoteResource', function($resource) {
var wrap = function(_) {
// forward declaration -- function redefined below
};
function extend(item) {
return angular.extend(new Note(), item);
}
var url = 'http://okigan.apiary.io/notes/:id';
var res = $resource(url, null, {
create: {
method: 'POST',
transformResponse: function(data, headersGetter) {
var item = angular.fromJson(data);
var headers = headersGetter();
// also handle HTTP 201 response
var extra = {
location: headers.location
};
var model = wrap(item);
angular.extend(model, extra);
return model;
}
},
query: {
method: 'GET',
isArray: true,
transformResponse: function(data, headersGetter) {
var items = angular.fromJson(data);
var models = [];
angular.forEach(items, function(item) {
models.push(wrap(item));
});
return models;
}
},
get: {
method: 'GET',
params: {
id: '@id'
},
transformResponse: function(data, headersGetter) {
var item = angular.fromJson(data);
var model = wrap(item);
return model;
}
}
});
res.url = url;
wrap = function(data) {
var T = Note;
// read up on http://javascript.crockford.com/prototypal.html
T.prototype = res.prototype;
var instance = new T();
angular.extend(instance, data);
return instance;
};
res.newModel = function() {
return wrap({});
};
return res;
});
app.controller('MainCtrl', function($scope, NoteResource) {
$scope.name = 'World';
$scope.notes = NoteResource.query();
$scope.newNotes = [];
$scope.spellCheckAllNotes = function() {
angular.forEach($scope.notes, function(note) {
note.spellCheck();
});
};
$scope.newNote = function() {
var note = NoteResource.newModel();
note.title = 'Buy cheese and bread for breakfast.';
$scope.newNotes.push(note);
note.$save().then(function() {
$scope.notes = NoteResource.query();
$scope.newNotes = [];
});
};
});
答案 1 :(得分:1)
<强>已更新强>
以下是一种可以继续将Note
构造函数合并到$resource
服务中的方法...
为从工厂返回的对象添加新的实例方法:
res.getNew = function(){
var newNote = new Note();
newNote.id = undefined; // new note doesn't have id set
newNote.checked = undefined; // don't need this data passed to server?
angular.extend(newNote, res);
return newNote;
}
此方法修改实例化的Note
对象(在创建新笔记时删除不需要传递给服务器的ID和其他数据),然后将其与$resource
合并服务并将该对象返回给调用者。
从控制器调用该方法,将其返回值分配给局部变量。您还可以从控制器修改其属性:
var note = NoteResource.getNew();
note.title = 'Eat a lot of junk food';
调用save
对象上的note
方法,将自身作为唯一参数传递:
note.save(note).$promise.then(function() {
$scope.notes = NoteResource.query();
$scope.newNotes = [];
});
在dev工具中观察并注意到这确实会导致使用包含note
属性的POST(之前的解决方案没有)发送JSON有效负载。
希望这个解决方案可以帮助您执行模型,而无需以非预期的方式使用工厂。