Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/400.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Ember.js问答题:保存/删除有很多数据_Javascript_Ember.js_Ember Data - Fatal编程技术网

Javascript Ember.js问答题:保存/删除有很多数据

Javascript Ember.js问答题:保存/删除有很多数据,javascript,ember.js,ember-data,Javascript,Ember.js,Ember Data,作为我的第一个余烬项目,我正在构建一个测验生成器,但我正在努力。我已经能够创建、编辑和删除测验,并将它们保存到本地存储中,但我在保存/删除每个测验的测验问题时遇到问题 我在约曼恩伯建造它。我试图向JSBin添加一个演示,但没有成功,因此我在这里创建了一个演示版本: 这是一个包含构建当前状态的zip文件: 下面是我的combined-scripts.js文件: (function() { var Quizmaker = window.Quizmaker = Ember.Application.c

作为我的第一个余烬项目,我正在构建一个测验生成器,但我正在努力。我已经能够创建、编辑和删除测验,并将它们保存到本地存储中,但我在保存/删除每个测验的测验问题时遇到问题

我在约曼恩伯建造它。我试图向JSBin添加一个演示,但没有成功,因此我在这里创建了一个演示版本: 这是一个包含构建当前状态的zip文件:

下面是我的combined-scripts.js文件:

(function() {

var Quizmaker = window.Quizmaker = Ember.Application.create();

/* Order and include as you please. */


})();

(function() {

/* global $ */

Quizmaker.QuizzesController = Ember.ObjectController.extend({
});

Quizmaker.NewController = Ember.ObjectController.extend({
    content: {},
    quiztypes: ['Multiple choice', 'List', 'Either/or'],
    actions: {
        save: function(){
            var title = $('#title').val();
            var excerpt = $('#excerpt').val();
            var quiztype = $('#quiztype').val();
            var fullname = $('#fullname').val();
            var submittedOn = new Date();
            var store = this.get('store');
            if (Ember.isEmpty(title)) {
                window.alert('Please enter a title');
                return false;
            } else if (Ember.isEmpty(quiztype)) {
                window.alert('Please enter a quiz type');
                return false;
            }
            var quiz = store.createRecord('quiz',{
                quiztype : quiztype,
                fullname : fullname,
                title : title,
                excerpt : excerpt,
                submittedOn : submittedOn
            });
            quiz.save();
            this.transitionToRoute('index');
        },
        cancel: function(){
            this.transitionToRoute('index');
        },
        createQuestion: function(){
            window.alert('This doesn\'t work for new questions. I don\'t know why. It works for existing questions.');
            var store = this.get('store');
            var question = store.createRecord('question',{
                question : 'Test question ' + new Date()
            });
            var model = this.get('model');
            var questions = this.get('questions');
            questions.pushObject(question);
            model.set('questions', questions);
            model.save();
        }
    }
});


Quizmaker.QuizController = Ember.ObjectController.extend({
    quiztypes: ['Multiple choice', 'Checklist', 'Boolean'],
    actions: {
        edit: function(){ 
            this.transitionToRoute('quiz.edit');
            this.set('isEditing', true);
        },
        doneEditing: function(){
            var model = this.get('model');
            var title = $('#title').val();
            var excerpt = $('#excerpt').val();
            var quiztype = $('#quiztype').val();
            var fullname = $('#fullname').val();
            var questions = this.get('questions');
            if (Ember.isEmpty(title)) {
                window.alert('Please enter a title');
                return false;
            } else if (Ember.isEmpty(quiztype)) {
                window.alert('Please enter a quiz type');
                return false;
            } else {
                this.set('isEditing', false);
                model.set('title', title);
                model.set('excerpt', excerpt);
                model.set('quiztype', quiztype);
                model.set('fullname', fullname);
                model.set('questions', questions);
                model.save();
                this.transitionToRoute('quiz');
            }
        },
        cancel: function(){
            if (window.confirm('Are you sure you want to abandon your changes?')){
                this.set('isEditing', false);
                this.transitionToRoute('quiz');
            }
        },
        remove: function(){
            if (window.confirm('Are you sure you want to delete this quiz?')){
                var quiz = this.get('model');
                quiz.destroyRecord();
                this.transitionToRoute('index');
            }
        },
        createQuestion: function(){
            var store = this.get('store');
            var question = store.createRecord('question',{
                question : 'Test question ' + new Date()
            });
            var model = this.get('model');
            var questions = this.get('questions');
            questions.pushObject(question);
            model.set('questions', questions);
            model.save();
        }
    }
});

Quizmaker.QuestionsController = Ember.ArrayController.extend({
    needs: 'quiz',
    quiz: Ember.computed.alias("controllers.quiz"),
    actions: {
        createQuestion: function(){
            var store = this.get('store');
            var question = store.createRecord('question',{
                question : 'Test question ' + new Date()
            });
            var quiz = this.get('quiz');
            var questions = quiz.get('questions');
            questions.pushObject(question);
            console.log(question);
        },
        removeQuestion: function(id){
            var question = this.findProperty('id', id);
            this.removeObject(question);
        }
    }
});

})();

(function() {

Quizmaker.Store = DS.Store.extend();
// Quizmaker.ApplicationAdapter = DS.FixtureAdapter;
Quizmaker.ApplicationAdapter = DS.LSAdapter.extend({
    namespace: 'quizzes'
});

})();

(function() {

/* global Ember */
Quizmaker.Quiz = DS.Model.extend({
  title : DS.attr('string'),
  excerpt : DS.attr('string'),
  fullname : DS.attr('string'),
  quiztype : DS.attr('string'),
  questions: DS.hasMany('question', {async: true}), //  via http://stackoverflow.com/questions/22494140/in-ember-js-how-do-i-create-a-computed-property-that-references-first-item-in-pr
  questionsCount: function() {
        return this.get('questions.length');
    }.property('questions.@each'), // via http://stackoverflow.com/questions/16463958/how-to-use-multiple-models-with-a-single-route-in-emberjs-ember-data
  // firstQuestion: function() {
  //   return this.get('questions.firstObject');
  // }.property('questions.firstObject')
  submittedOn : DS.attr('date')
});

Quizmaker.Question = DS.Model.extend({
    quiz: DS.belongsTo('quiz'),
    question: DS.attr('string'),
    answers: DS.attr('string')
});

// delete below here if you do not want fixtures
Quizmaker.Quiz.FIXTURES = [
    {
        id: 0,
        title: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit',
        excerpt: 'Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry\'s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.',
        quiztype: 'Boolean',
        fullname: 'Full Name',
        submittedOn: null
    }
];
Quizmaker.Question.FIXTURES = [
    {
        id: 0,
        question: 'Test question Lorem ipsum dolor sit amet, consectetur adipiscing elit',
        quiz: 0,
        answers: [
            { answer: 'alpha', weight: 0 },
            { answer: 'beta', weight: 5 }
        ]
    }
];


})();

(function() {

Quizmaker.ApplicationRoute = Ember.Route.extend({
    model: function () {
        return this.get('store').findAll('quiz');
    }
});

Quizmaker.QuizzesRoute = Ember.Route.extend({
    model: function() {
        return this.get('store').find('quiz');
    }
});

Quizmaker.QuizRoute = Ember.Route.extend({
    model: function(params) {
        return this.get('store').find('quiz', params.quiz_id);
    }
});

Quizmaker.QuestionsRoute = Ember.Route.extend({
    controllerName: 'quiz',
    model: function() {
        return this.store.findAll('question');
    }
});

})();

(function() {

Quizmaker.QuizView = Ember.View.extend({
    keyDown: function(e) {
        var esc = 27;
        if(e.keyCode === esc){
            this.get('controller').send('cancel');
        }
    }
});

// Give the text fields one way value binding so they don't automatically update
Quizmaker.TextField = Ember.TextField.extend({
    valueBinding: Ember.Binding.oneWay('source')
});
Quizmaker.TextArea = Ember.TextArea.extend({
    valueBinding: Ember.Binding.oneWay('source')
});
Quizmaker.Select = Ember.Select.extend({
    valueBinding: Ember.Binding.oneWay('source')
});

})();

(function() {

Quizmaker.QuizzesView = Ember.View.extend({
});


})();

(function() {

Quizmaker.Router.map(function () {
    // Add your routes here
    this.resource('index',{path : '/'});
    this.resource('new' , {path : '/quiz/new'});
    this.resource('quizzes' , {path : '/quizzes'});
    this.resource('questions' , {path : '/questions'});

    this.resource('quiz', { path: '/quiz/:quiz_id' }, function(){
        this.route('edit', { path: '/edit' });
    });
});

})();

(function() {

/* global moment */
Ember.Handlebars.helper('format-date', function(date){
    return moment(date).fromNow();
});

})();
这里是quick.hbs:

{{#if isEditing}}
    <h1>Edit quiz</h1>
    {{partial "editform"}}
{{else}}
    <h1>{{title}}</h1>
    <h4>A <em style="text-transform: lowercase;">{{quiztype}}</em> quiz by {{fullname}} <small class="muted">{{format-date submittedOn}}</small></h4>
    <hr>
    <p class="lead">{{excerpt}}</p>
    <button type="submit" class="btn btn-default" {{action 'edit'}}>Edit</button>
    <button class="btn btn-danger pull-right" {{action 'remove'}}>Delete Quiz</button>
{{/if}}
这是_editform.hbs:

        <form class="form-horizontal" role="form">
        <div class="form-group">
            <label for="title" class="col-sm-2 control-label">Title</label>
            <div class="col-sm-10">
                {{!-- {{#view Quizmaker.TextInputView}}
                {{/view}} --}}
                {{!-- <input type="text" class="form-control" id="title" name="title" placeholder="Title of the quiz" required> --}}
                {{view Quizmaker.TextField type="text" class="form-control" id="title" name="title" sourceBinding="title" placeholder="Title of the quiz" required="required" }}
            </div>
        </div>
        <div class="form-group">
            <label for="excerpt" class="col-sm-2 control-label">Excerpt</label>
            <div class="col-sm-10">
                {{!-- <textarea class="form-control" id="excerpt" name="excerpt" placeholder="Short description of the quiz" required></textarea> --}}
                {{view Quizmaker.TextArea class="form-control" id="excerpt" name="excerpt" sourceBinding="excerpt" placeholder="Short description of the quiz" rows="3" required="required" }}
            </div>
        </div>
        <div class="form-group">
            <label for="fullname" class="col-sm-2 control-label">Author</label>
            <div class="col-sm-10">
                {{!-- <input type="text" class="form-control" id="fullname" name="fullname" placeholder="Enter your Full Name like Alan Smithee" required> --}}
                {{view Quizmaker.TextField type="text" class="form-control" id="fullname" name="fullname" sourceBinding="fullname" placeholder="Enter your full name, e.g. Alan Smithee" required="required" }}
            </div>
        </div>
        <div class="form-group">
            <label for="quiztype" class="col-sm-2 control-label">Quiz type</label>
            <div class="col-sm-10">
                {{view Quizmaker.Select id="quiztype" name="quiztype" class="form-control" viewName="select" content=quiztypes prompt="Pick a type:" sourceBinding="quiztype"}}
            </div>
        </div>
        <div class="form-group">
            <label for="quiztype" class="col-sm-2 control-label">Questions ({{questionsCount}})</label>
            <div class="col-sm-10">
                {{render "questions" questions}}
            </div>
        </div>
        <div class="form-group">
            <div class="col-sm-offset-2 col-sm-10">
                {{#if isEditing}}
                    <button type="submit" class="btn btn-success" {{action 'doneEditing'}}>Save</button>
                    <button class="btn btn-warning pull-right" {{action 'cancel'}}>Cancel</button>
                {{else}}
                    <button type="submit" class="btn btn-success" {{action 'save'}}>Save</button>
                    <button class="btn btn-warning pull-right" {{action 'cancel'}}>Cancel</button>
                {{/if}}
            </div>
        </div>
    </form>

And this is questions.hbs:

    <p><button class="btn btn-info btn-sm" {{action 'createQuestion'}}><span class="glyphicon glyphicon-plus"></span> Add new question</button></p>
<table class="table table-striped">
    {{#each model}}
        <tr>
            <td>{{this.question}}</td>
            <td>{{this.id}}</td>
            <td><button class="btn btn-danger btn-xs pull-right" {{action 'removeQuestion' id}}>Delete</button></td>
        </tr>
    {{/each}}
</table>
如果有人能指出我可以改进它的方法,我将非常感激。我尝试过实现我能找到的每一种方法来保存或删除有很多数据,但它总是抛出不同的错误,我真的不确定从这里开始


我还试图找出如何根据是否显示/编辑路由而不是通过操作激活它来切换isEditing状态。

让我们将其分解为两个不同的项目,从上到下

显示编辑模式与查看模式的诀窍是利用在每个资源的根上呈现的自由索引路由

您可以将测验模板更改为出口

{{outlet}}
并创建一个测验/索引模板,最初保存测验数据。此模板仅在导航到/quick/123/编辑时位于/quick/123时显示。索引模板将替换为编辑模板。您可能希望使用modelFor将模型从资源返回到两个路由

App.Router.map(function() {
  this.resource('foo', {path:'/'},function(){
    this.route('edit');
  })
});

App.FooRoute = Em.Route.extend({
  model: function() {
    return [{color:'red'}, {color:'yellow'},{color: 'blue'}];
  }
});

App.FooIndexRoute = Ember.Route.extend({
  model: function() {
    return this.modelFor('foo');
  }
});


App.FooEditRoute = Ember.Route.extend({
  model: function() {
    return this.modelFor('foo');
  }
});
在余烬数据中,如果您有两种记录类型,且每种记录类型都相互关联:

App.FooRecord = DS.Record.extend({
  bars: DS.hasMany('bar')
});

App.BarRecord = DS.Record.extend({
  foo: DS.belongsTo('foo')
});
让我们创建并关联两个记录:

var foo = store.create('foo');

var bar = store.create('bar');

foo.get('bars').pushObject(bar);

bar.set('foo', foo);
现在让我们保存,并查看余烬数据将执行哪些操作:

foo.save();
// json sent
{
  foo: {}
}
// responds with id 1

bar.save();
// json sent
{
  bar: {
    foo: 1
  }
}
如果hasMany关系是来自不同模型类型的相关属性,则Ember Data选择不保存该关系


谢谢我已经使用了你的第一个答案:路由,让它现在起作用,但我不理解你关于保存很多关系的评论,这是我一直特别挣扎的部分。你能详细说明你的答案吗?或者提供一个解决方案的例子吗?对不起,最后我被赶着写了,我会试着把事情弄清楚。