Model Sencha Touch 1.xx-从服务器代理加载关联模型
我一直在尝试从关联的模型存储中检索数据。请允许我简要概述一下我正在努力实现的目标 我需要一个测验列表,在点击测验时,它会显示一个问题列表。点击一个问题后,您将获得相关的多项选择答案(可能是带有按钮的数据视图或其他列表) 在早期的测试版中,我使用了一个平面树存储来显示测验,但这在美学上受到了限制,并且不允许我很容易地将数据与api同步,因此我尝试让相关模型工作。我在网上发现了类似的问题,但我不太明白我在追求什么 以下是相关代码(在MVC设置中)。我有3个相关模型: QuizModel.js:Model Sencha Touch 1.xx-从服务器代理加载关联模型,model,proxy,extjs,store,model-associations,Model,Proxy,Extjs,Store,Model Associations,我一直在尝试从关联的模型存储中检索数据。请允许我简要概述一下我正在努力实现的目标 我需要一个测验列表,在点击测验时,它会显示一个问题列表。点击一个问题后,您将获得相关的多项选择答案(可能是带有按钮的数据视图或其他列表) 在早期的测试版中,我使用了一个平面树存储来显示测验,但这在美学上受到了限制,并且不允许我很容易地将数据与api同步,因此我尝试让相关模型工作。我在网上发现了类似的问题,但我不太明白我在追求什么 以下是相关代码(在MVC设置中)。我有3个相关模型: QuizModel.js: ap
app.models.QuizModel = Ext.regModel("QuizModel", {
fields: [
{ name: 'id', type: 'int' },
{ name: 'studentid', type: 'int' },
{ name: 'dateAllocated', type: 'string' },
{ name: 'category', type: 'string' },
],
associations: [
{type: 'hasMany', model: 'QuestionModel', name: 'questions'},
],
proxy: {
type: 'rest',
actionMethods: {create: "POST", read: "POST", update: "PUT", destroy: "DELETE"},
url: 'http://localhost/bm/core/api/quiz',
reader: {
type: 'json',
root: 'quizes'
}
}
});
app.stores.QuizStore = new Ext.data.Store({
model: "QuizModel",
storeId: 'quizStore'
});
QuestionModel.js:
app.models.QuestionModel = Ext.regModel("QuestionModel", {
fields: [
{ name: 'id', type: 'int' },
{ name: 'quizmodel_id', type: 'int'},
{ name: 'prompt', type: 'string' },
{ name: 'level', type: 'int' },
{ name: 'categoty', type: 'string' }
],
associations: [
{type: 'hasMany', model: 'AnswerModel', name: 'answers'},
{type: 'belongsTo', model: 'QuizModel'}
]
});
AnswerModel.js:
app.models.AnswerModel = Ext.regModel("AnswerModel", {
fields: [
{ name: 'id', type: 'int' },
{ name: 'questionmodel_id', type: 'int' },
{ name: 'prompt', type: 'string' },
{ name: 'correct', type: 'string' }
],
associations: [
{type: 'belongsTo', model: 'QuestionModel'}
]
});
QuizController.js:
app.controllers.QuizController = new Ext.Controller({
index: function(options) {
console.log('home');
},
quizTap: function(options){
var currentQuiz = app.stores.QuizStore.getAt(options.index);
var questions = currentQuiz.questions().load().getAt(0);
app.views.questionList.updateWithRecord(questions);
app.views.viewport.setActiveItem(
app.views.questionList, options.animation
);
}
});
最后,我的rest API响应如下所示:
{
"status" : true,
"quizes" : [{
"id" : "1",
"category" : "Privacy",
"date_allocated" : "1329363878",
"questions" : [{
"id" : "1",
"prompt" : "Lorem ipsum dolor sit amet?",
"answers" : [{
"id" : "1",
"correct" : "1",
"prompt" : "yes"
},
{
"id" : "2",
"correct" : "0",
"prompt" : "no"
}]
}]
}]
}
这导致:
“未捕获错误:您正在使用服务器代理,但尚未为其提供url。”
现在,我的QuizModel具有与RESTAPI通信所需的代理,但从questions()加载似乎使用默认代理。我已经尝试使用所需的参数(包括url和必要的api键)配置加载调用,但这似乎不起作用。我似乎找不到任何关于我应该如何做到这一点的文档,大多数相关的帖子都只讨论本地存储。请帮忙
编辑:添加我的问题列表视图:
BuddeMobile.views.QuestionList = Ext.extend(Ext.Panel, {
title: 'Quiz',
iconCls: 'quiz',
cls: 'question',
scroll: 'vertical',
initComponent: function(){
Ext.apply(this, {
dockedItems: [{
xtype: 'toolbar',
title: 'Quiz'
}],
items: [{
xtype: 'list',
itemTpl: '<div class="quiz-question">{prompt}</div>',
store: 'quizStore',
listeners: {
itemtap: function (list, index, el, e){
console.log('question tap',el);
}
}
}]
});
BuddeMobile.views.QuestionList.superclass.initComponent.call(this, arguments);
},
updateWithRecord: function(record) {
var toolbar = this.getDockedItems()[0];
toolbar.setTitle(record.get('category')); //works
var list = this.items.get(0);
console.log(record.questions()); //prints out mixed collection of questions
var question1 = record.questions().getAt(0); //testing
console.log(question1.answers()); //prints out mixed collection for first question's answers
list.update(record.questions()); //does not work. How can I populate the list??
}
});
BuddeMobile.views.QuestionList=Ext.extend(Ext.Panel{
标题:"小测验",,
iconCls:“测验”,
cls:‘问题’,
滚动:‘垂直’,
initComponent:function(){
Ext.apply(本{
摘要:[{
xtype:'工具栏',
标题:“测验”
}],
项目:[{
xtype:'列表',
itemTpl:“{prompt}”,
商店:“quizStore”,
听众:{
itemtap:功能(列表、索引、el、e){
console.log('question tap',el);
}
}
}]
});
BuddeMobile.views.QuestionList.superclass.initComponent.call(这是参数);
},
updateWithRecord:函数(记录){
var toolbar=this.getDockedItems()[0];
toolbar.setTitle(record.get('category');//有效
var list=this.items.get(0);
console.log(record.questions());//打印出问题的混合集合
var question1=record.questions().getAt(0);//测试
console.log(question1.answers());//打印第一个问题答案的混合集合
list.update(record.questions());//不起作用。如何填充列表??
}
});
如您所见,我可以获得所需的数据(在登录时加载存储),但我不知道如何使列表使用数据子集。我已经尝试了更新功能,但这不是做很多 我现在通过使用单独的存储,而不是试图让单个嵌套存储来完成所有工作,从而使测验正常运行。要做到这一点,我必须确保我的服务器使用相应的外键处理JSON模型。我的模型和商店示例:
app.models.Quiz = Ext.regModel("Quiz", {
fields: [
{ name: 'id', type: 'int' },
{ name: 'studentid', type: 'int' },
{ name: 'dateAllocated', type: 'string' },
{ name: 'category', type: 'string' },
],
associations: [
{type: 'hasMany', model: 'Question', name: 'questions'},
],
proxy: {
type: 'rest',
actionMethods: {create: "POST", read: "POST", update: "PUT", destroy: "DELETE"},
url: 'http://localhost/bm/core/api/quiz',
reader: {
type: 'json',
root: 'quizes',
id: 'id'
}
}
});
app.stores.QuizStore = new Ext.data.Store({
model: "Quiz",
storeId: 'quizStore'
});
对于问题模型,请注意测验id的字段:
app.models.Question = Ext.regModel("Question", {
fields: [
{ name: 'id', type: 'int' },
{ name: 'quiz_id', type: 'int'},
{ name: 'prompt', type: 'string' },
{ name: 'level', type: 'int' },
{ name: 'category', type: 'string' }
],
associations: [
{type: 'hasMany', model: 'Answer', name: 'answers'},
{type: 'belongsTo', model: 'Quiz'}
],
proxy: {
type: 'rest',
actionMethods: {create: "POST", read: "POST", update: "PUT", destroy: "DELETE"},
url: 'http://localhost/bm/core/api/questions',
reader: {
type: 'json',
root: 'questions',
id: 'id'
}
}
});
app.stores.QuestionStore = new Ext.data.Store({
model: "Question",
storeId: 'questionStore'
});
此设置允许我对每个商店(列表)有单独的视图,这些视图可以根据选择进行筛选。请注意,我的API仅为登录用户加载问答/问题/答案,因此在登录时加载不会太多
从控制器筛选特定列表的存储的示例:
showQuiz: function(options){
//id passed from List's itemTap event
var currentQuiz = app.stores.QuizStore.getById(options.id);
app.stores.QuestionStore.clearFilter();
//filter questions by selected quiz
app.stores.QuestionStore.filter({
property: 'quiz_id',
value: options.id,
exactMatch: true
});
//pass quiz record for setting toolbar title etc
app.views.questionList.updateWithRecord(currentQuiz);
app.views.quiz.setActiveItem(
app.views.questionList, options.animation
);
}
希望这能帮助任何遇到同样问题的人 我想我的问题是,一个列表绑定到一个商店。为什么我不能让列表显示我想要的内容?我在这里使用单个存储的选项是什么?我重新安排了REST API,将登录学生的所有测验、问题和答案加载到单独的存储中,然后根据选择的测验/问题对每个存储使用过滤器。这是一个很大的变化,但到目前为止已经奏效了!实际上,现在有了这3个独立的存储,我的外键将显示为0,因此我的过滤器将无法工作。GRRRRRR