您返回的 json 将主要反映灯具。我最近和你有几乎相同的问题,所以我在 Grails 中构建了一个后端,在 SC 中构建了一个前端,只是为了探索存储和数据源。我的模型是:
Scds.Project = SC.Record.extend(
/** @scope Scds.Project.prototype */ {
primaryKey: 'id',
name: SC.Record.attr(String),
tasks: SC.Record.toMany("Scds.Task", {
isMaster: YES,
inverse: 'project'
})
});
Scds.Task = SC.Record.extend(
/** @scope Scds.Task.prototype */ {
name: SC.Record.attr(String),
project: SC.Record.toOne("Scds.Project", {
isMaster: NO
})
});
为项目返回的 json 是
[{"id":1,"name":"Project 1","tasks":[1,2,3,4,5]},{"id":2,"name":"Project 2","tasks":[6,7,8]}]
当我选择一个项目时,为任务返回的 json 是
{"id":1,"name":"task 1"}
显然,这只是 1 个任务的 json。如果您查看项目 json,您会看到我在其中放置了一个带有 id 的“任务”数组——这就是内部人员如何知道要获取哪些任务的方式。所以要回答你的第一个问题,你不需要从孩子到父母的 id,你需要父母与所有孩子一起加载,所以 json 与灯具不完全匹配。
现在,它变得有点棘手。当我加载应用程序时,我会进行查询以获取所有项目。存储在数据源上调用fetch 方法。这是我的实现。
Scds.PROJECTS_QUERY = SC.Query.local(Scds.Project);
var projects = Scds.store.find(Scds.PROJECTS_QUERY);
...
fetch: function(store, query) {
console.log('fetch called');
if (query === Scds.PROJECTS_QUERY) {
console.log('fetch projects');
SC.Request.getUrl('scds/project/list').json().
notify(this, '_projectsLoaded', store, query).
send();
} else if (query === Scds.TASKS_QUERY) {
console.log('tasks query');
}
return YES; // return YES if you handled the query
},
_projectsLoaded: function(response, store, query) {
console.log('projects loaded....');
if (SC.ok(response)) {
var recordType = query.get('recordType'),
records = response.get('body');
store.loadRecords(recordType, records);
store.dataSourceDidFetchQuery(query);
Scds.Statechart.sendEvent('projectsLoaded')
} else {
console.log('oops...error loading projects');
// Tell the store that your server returned an error
store.dataSourceDidErrorQuery(query, response);
}
}
这将获得项目,但不会获得任务。 Sproutcore 知道,只要我访问项目上的任务数组,它就需要获取它们。它的作用是在数据源中调用retrieveRecords。该方法依次为 tasks 数组中的每个 id 调用 retrieveRecord。我的 retrieveRecord 方法看起来像
retrieveRecord: function(store, storeKey) {
var id = Scds.store.idFor(storeKey);
console.log('retrieveRecord called with [storeKey, id] [%@, %@]'.fmt(storeKey, id));
SC.Request.getUrl('scds/task/get/%@'.fmt(id)).json().
notify(this, "_didRetrieveRecord", store, storeKey).
send();
return YES;
},
_didRetrieveRecord: function(response, store, storeKey) {
if (SC.ok(response)) {
console.log('succesfully loaded task %@'.fmt(response.get('body')));
var dataHash = response.get('body');
store.dataSourceDidComplete(storeKey, dataHash);
} ...
},
请注意,您应该使用 sc-gen 来生成您的数据源,因为它提供了一个相当完善的存根,可以引导您使用您需要实现的方法。它不提供retrieveMethods 实现,但如果您不想为正在加载的每个子记录执行单个请求,您可以提供自己的实现。
请注意,您始终可以选择。如果我愿意,我可以创建一个任务查询并预先加载所有任务数据,这样当我点击一个项目时我就不需要去我的服务器了。所以在回答你的第二个问题时,这取决于。您可以在单击客户端时加载品牌,也可以预先加载所有数据,如果没有那么多数据,这可能是个好主意。