Sencha Touch 1.xx - загрузка связанных моделей с прокси сервера - PullRequest
2 голосов
/ 20 февраля 2012

Я застрял, пытаясь получить данные из связанного хранилища моделей.Позвольте мне дать краткий обзор того, чего я пытаюсь достичь.

Мне нужен Список тестов, и после нажатия на тест он покажет Список вопросов.После нажатия на вопрос вы получите соответствующие ответы с несколькими вариантами ответов (возможно, просмотр данных с помощью кнопок или другого списка).

В более ранней бета-версии я использовал хранилище плоских деревьев для отображения теста, но это было ограничение вэстетики и не позволили мне очень легко синхронизировать мои данные с API, и поэтому я пытаюсь заставить работать связанные модели вместо этого.Я обнаружил, что аналогичные проблемы в сети не могут полностью понять, что мне нужно.

Вот соответствующий код (в настройке MVC).У меня есть 3 связанные модели:

QuizModel.js:

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
        );
    }
});

и, наконец, мой ответ 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"
                    }]
            }]
     }]
}

В результате:

"UncaughtОшибка: вы используете ServerProxy, но не указали URL-адрес. ".

Теперь у моего QuizModel есть требуемый прокси-сервер для связи с моим REST API, но загрузка из вопросов (), похоже, используетпрокси по умолчанию.Я попытался настроить вызов загрузки с необходимыми параметрами (включая 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??
    }


});

Как вы можете видеть, я могу получить нужные мне данные (как я загружаю хранилище при входе в систему), но я нене знаю, как сделать список использовать подмножество данных.Я попробовал функцию обновления, но это мало что делает!

1 Ответ

1 голос
/ 22 февраля 2012

Теперь моя викторина работает правильно, используя отдельные хранилища, вместо того, чтобы заставить все вложенное хранилище делать все.Чтобы сделать это, я должен был убедиться, что мой сервер использует модели 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'
});

и модель вопроса, обратите внимание на поле для quiz_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
        );

    }

Надеюсь, это поможет любому столкнуться с той же проблемой!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...