Ember.js测验问题:保存/删除有很多数据 [英] Ember.js quiz questions: save/delete hasMany data

查看:297
本文介绍了Ember.js测验问题:保存/删除有很多数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在建立一个测验发生器作为我的第一个Ember项目,但我正在努力。我已经能够创建,编辑和删除测验并将其保存到本地存储,但是我无法保存/删除每个测验的测验问题。



在Yeoman-Ember建造它。我试图添加一个演示到JSBin,但它没有工作,所以我有一个演示版本在这里:
http://test.richardwestenra.com/embertest/
,这里是一个包含构建的当前状态的zip: http://test.richardwestenra.com/embertest/dev.zip



这是我的组合 - scripts.js文件:

 (function(){

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

/ *可以随意订购并包含* /


})();

(function(){

/ *全局$ * /

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

Quizmaker.NewController = Ember.ObjectController.extend({
content:{},
quiztypes:['Multiple choice','List','Either /或'',
actions:{
save:function(){
var title = $('#title')。val();
var 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('请输入一个标题');
返回false;
} else if(Ember.isEmpty(quiztype)){
window.alert('请输入测验类型');
返回false;
}
var quiz = store.createRecord('quiz',{
quiztype:quiztype,
fullname:fullname,
title:title,
摘录:摘录,
submittedOn: submitOn
});
quiz.save();
this.transitionToRoute('index');
},
cancel:function(){
this.transitionToRoute('index');
},
createQuestion:function(){
window.alert('这不适用于新的问题,我不知道为什么,它适用于现有的问题。');
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' b $ b var questions = this.get('questions');
if(Ember.isEmpty(title)){
window.alert('请输入标题');
return false;
} else if(Ember.isEmpty(quiztype)){
window.alert('请输入测验类型');
返回fals e;
} else {
this.set('isEditing',false);
model.set('title',title);
model.set('excerpt',摘录);
model.set('quiztype',quiztype);
model.set('fullname',fullname);
model.set('questions',questions);
model.save();
this.transitionToRoute('quiz');
}
},
取消:function(){
如果(window.confirm('你确定要放弃你的更改吗')){
this.set('isEditing',false);
this.transitionToRoute('quiz');
}
},
删除:function(){
if(window.confirm('你确定要删除这个测验吗?')){
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({
需要:'quiz',
quiz:Ember.computed.alias(controllers.quiz),
actions:{
createQuestion:function(){
var store = this.get('store');
var question = store.createRecord('question',{
问题:'测试问题'+新日期()
});
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(){

/ *全局Ember * /
Quizmaker.Quiz = DS.Model.extend({
title:DS。 attr('string'),
摘录:DS.attr('string'),
fullname:DS.attr('string'),
quiztype:DS.attr('string' ),
问题:DS.hasMany('question',{async:true}),//通过http://stackoverflow.com/questions/22494140/in-ember-js-how-do-i- create-a-calculated-property-the-references-first-item-in-pr
questionsCount:function(){
return this.get('questions.length');
} .property('questions。@ each'),//通过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')
submitOn:DS.attr('date')
});

Quizmaker.Question = DS.Model.extend({
quiz:DS.belongsTo('quiz' ),
q uestion:DS.attr('string'),
答案:DS.attr('string')
});

//如果您不想要夹具
,请删除以下内容:Quizmaker.Quiz.FIXTURES = [
{
id:0,
title:' Lorem ipsum dolor sit amet,consectetur adipiscing elit',
摘录:Lorem Ipsum只是印刷和排版行业的虚拟文字。自从15世纪15年代以来,Lorem Ipsum一直是行业的标准虚拟文本,当时一个未知的打印机拿了一个类型的厨房,并打了一个类型的样本书。它已经生存了不止五个世纪,而且还跨越了电子排版,基本保持不变。它在二十世纪六十年代得到普及,发行了包含Lorem Ipsum段落的Letraset表,最近还有一些桌面出版软件,如Aldus PageMaker,包括Lorem Ipsum的版本。
quiztype:'Boolean',
fullname :'全名',
submittedOn:null
}
];
Quizmaker.Question.FIXTURES = [
{
id:0,
问题:'测试问题Lorem ipsum dolor sit amet,consectetur adipiscing elit',
quiz: 0,
答案:[
{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);
}


$ b 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');
}
}
});

//给文本字段一种方式绑定,所以它们不会自动更新
Quizmaker.TextField = Ember.TextField.extend({
valueBinding: Ember.Binding.oneWay('source')
});
Quizmaker.TextArea = Ember.TextArea.extend({
valueBinding:Ember.Binding.oneWay('source')
$ b Quizmaker.Select = Ember.Select.extend({
valueBinding:Ember.Binding.oneWay('source')
});

})();

(function(){

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


})();

(function(){

Quizmaker.Router.map(function(){
//在此添加您的路由
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(){

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

})();

这是quiz.hbs:

  {{#if isEditing}} 
< h1>编辑测验< / h1>
{{partialeditform}}
{{else}}
< h1> {{title}}< / h1>
< h4> A< em style =text-transform:smallcase;> {{quiztype}}< / em> {{fullname}}测试< small class =muted> {{format-date submittedOn}}< / small>< / h4>
< hr>
< p class =lead> {{摘录}}< / p>
< button type =submitclass =btn btn-default{{action'edit'}}>编辑< / button>
< button class =btn btn-danger pull-right{{action'remove'}}>删除测验< / button>
{{/ if}}

这是_editform.hbs:

 < form class =form-horizo​​ntalrole =form> 
< div class =form-group>
< label for =titleclass =col-sm-2 control-label> Title< / label>
< div class =col-sm-10>
{{! - {{#查询Quizmaker.TextInputView}}
{{/ view}} - }}
{{! - < input type =textclass =form-controlid =titlename =titleplaceholder =所需的测验题目> - }}
{{查看Quizmaker.TextField类型=textclass =form-controlid =titlename =titlesourceBinding =titleplaceholder =题目的测验 =required}}
< / div>
< / div>
< div class =form-group>
< label for =excerptclass =col-sm-2 control-label>摘录< / label>
< div class =col-sm-10>
{{! - < textarea class =form-controlid =excerptname =excerptplaceholder =需要简短描述测验>< / textarea> - }}
{{查看Quizmaker.TextArea class =form-controlid =excerptname =excerptsourceBinding =excerpt占位符=测验的简短描述rows =3 required =required}}
< / div>
< / div>
< div class =form-group>
< label for =fullnameclass =col-sm-2 control-label>作者< / label>
< div class =col-sm-10>
{{! - < input type =textclass =form-controlid =fullnamename =fullnameplaceholder =输入您的全名,如Alan Smithee必需> - }}
{{view Quizmaker.TextField type =textclass =form-controlid =fullnamename =fullnamesourceBinding =fullnameplaceholder =输入您的全名, Alan Smitheerequired =required}}
< / div>
< / div>
< div class =form-group>
< label for =quiztypeclass =col-sm-2 control-label>测验类型< / label>
< div class =col-sm-10>
{{查看Quizmaker.Select id =quiztypename =quiztypeclass =form-controlviewName =selectcontent = quiztypes prompt =选择一个类型:sourceBinding =quiztype}}
< / div>
< / div>
< div class =form-group>
< label for =quiztypeclass =col-sm-2 control-label>问题({{questionsCount}})< / label>
< div class =col-sm-10>
{{renderquestionsquestions}}
< / div>
< / div>
< div class =form-group>
< div class =col-sm-offset-2 col-sm-10>
{{#if isEditing}}
< button type =submitclass =btn btn-success{{action'doneEditing'}}>保存< / button>
< button class =btn btn-warning pull-right{{action'cancel'}}>取消< / button>
{{else}}
< button type =submitclass =btn btn-success{{action'save'}}>保存< / button>
< button class =btn btn-warning pull-right{{action'cancel'}}>取消< / button>
{{/ if}}
< / div>
< / div>
< / form>

这是question.hbs:

< p>< button class =btn btn-info btn-sm{{action'createQuestion'}}> ;< span class =glyphicon glyphicon-plus>< / span>添加新问题< / 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}}>删除< / button>< / td>
< / tr>
{{/ each}}
< / table>

如果有人可以指出我可以改进的方法,我将非常感激。我已经尝试实现我可以找到的每个方法来保存或删除hasMany数据,但总是会引发不同的错误,我不太确定从哪里进行。



我还想弄清楚如何根据/ edit路由是否显示(而不是由动作激活)来切换isEditing状态。 / p>

解决方案

让我们将它分解成两个不同的项目,最后一个。



显示编辑模式与视图模式的技巧是利用在每个资源根目录下呈现的免费索引路由。



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

  {{outlet}} 

并创建一个测验/ index 原始持有您的测验数据的模板。当您导航到 / quiz / 123 / edit 时,此模板将仅显示在 / quiz / 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');
}
});

http://emberjs.jsbin.com/lodeviyu/1/edit



在Ember Data中,如果您有两种记录类型每个都有一个关系:

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

现在让我们保存,看看Ember Data会做什么:

  foo.save(); 
// json发送
{
foo:{}
}
//响应id 1

bar.save();
// json sent
{
bar:{
foo:1
}
}
pre>

Ember数据选择不保存hasMany关系,如果它们是来自不同模型类型的相关的belongsTo。



https://github.com/emberjs/data/commit/7f752ad15eb9b9454e3da3f4e0b8c487cdc70ff0#commitcomment -6078838


I'm building a quiz generator as my first Ember project, but I'm struggling. I've been able to create, edit and delete quizzes and save them to localstorage, but I'm having trouble saving/deleting quiz questions for each quiz.

I'm building it in Yeoman-Ember. I tried to add a demo to JSBin but it didn't work, so I've got a demo build here: http://test.richardwestenra.com/embertest/ and here's a zip containing the current state of the build: http://test.richardwestenra.com/embertest/dev.zip

Here's my combined-scripts.js file:

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

})();

This is quiz.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}}

This is _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>

If anyone can point out ways I can improve it, I'd be very grateful. I've tried implementing every method I can find to get it to save or delete hasMany data but it always throws different errors and I'm not really sure where to proceed from here.

I'm also trying to figure out how to toggle the isEditing state depending on whether the /edit route is displayed (instead of having it activated by an action).

解决方案

let's break this down into two different items, last to first.

The trick in showing the edit mode versus view mode is to take advantage of the free index route which is rendered at the root of every resource.

You can change your quiz template to be an outlet

{{outlet}}

and create a quiz/index template which originally held your quiz data. This template will only show up when you are at /quiz/123 when you navigate to /quiz/123/edit the index template will be replaced with the edit template. (You'll probably want to return the model from the resource to both routes using 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');
  }
});

http://emberjs.jsbin.com/lodeviyu/1/edit

In Ember Data if you have two record types that each have a relation to each other:

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

App.BarRecord = DS.Record.extend({
  foo: DS.belongsTo('foo')
});

Let's create and associate two records:

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

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

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

bar.set('foo', foo);

Now let's save, and see what Ember Data will do:

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

bar.save();
// json sent
{
  bar: {
    foo: 1
  }
}

Ember Data chooses not to save the hasMany relationship if their is a correlated belongsTo from a different model type.

https://github.com/emberjs/data/commit/7f752ad15eb9b9454e3da3f4e0b8c487cdc70ff0#commitcomment-6078838

这篇关于Ember.js测验问题:保存/删除有很多数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆