2013-02-28 54 views
2

所有我想實現一個列表是這個示例應用程序:〜\玩-2.1.0 \樣本\ java的\形成Playframework POST到控制器

更新後的最新代碼:

question.scala.html樣子:

@(questionForm: Form[Question]) 

@import helper._ 
@import helper.twitterBootstrap._ 



@answerField(field: Field, className: String = "answer") = { 

<div class="twipsies well @className"> 
    <table> 
     <tr> 
      <td> @checkbox(field("addRight"),'_label -> "Add")</td> 
      <td> @checkbox(field("editRight"),'_label -> "Edit")</td> 
      <td> @checkbox(field("delRight"),'_label -> "Delete")</td> 
      <td> @checkbox(field("viewRight"),'_label -> "View")</td> 
     </tr> 
    </table> 
</div> 

} 


@if(questionForm.hasErrors) { 
    <div class="alert-message error"> 
     <p><strong>Oops</strong> Please fix all errors</p> 
    </div> 
} 

@helper.form(action = routes.Questions.submit, 'id -> "form") { 

    <fieldset> 

     @inputText(
      questionForm("name"), 
      '_label -> "Name of a Right" 
     ) 

     @inputText(
      questionForm("namex"), 
      '_label -> "Name of a Right" 
     ) 

     <div class="answers"> 

      @repeat(questionForm("answers"), min = 0) { answer => 
       @answerField(answer) 
      } 



      @** 
      * Keep an hidden block that will be used as template for Javascript copy code 
      * answer_template is only css style to make it hidden (look main.css and declare your own answer_template at bottom) 
      **@ 
      @answerField(
       questionForm("answers"), 
       className = "answer_template" 
      ) 

      <div class="clearfix"> 
       <div class="input"> 
        <a class="addAnswer btn success">Add </a> 
       </div> 
      </div> 

     </div> 
    </fieldset> 

    <div class="actions"> 
     <input type="submit" class="btn primary" value="Insert"> 
    </div> 

} 

<script type="text/javascript" charset="utf-8"> 

     $('.removeAnswer').on('click', function(e) { 
     var answers = $(this).parents('.answers'); 
     $(this).parents('.answer').remove(); 
     renumber(answers); 
     }); 

     $('.addAnswer').on('click', function(e) { 
     var answers = $(this).parents('.answers'); 
     var template = $('.answer_template', answers); 
     template.before('<div class="clearfix answer">' + template.html() + '</div>'); 
     renumber(answers); 
     }); 

     $('#form').submit(function() { 
     $('.answer_template').remove() 
     }); 

     // -- renumber fields 
     // This is probably not the easiest way to do it. A jQuery plugin would help. 

     var renumber = function(answers) { 
     $('.answer').each(function(i) { 
     $('input', this).each(function() { 
     $(this).attr('name', $(this).attr('name').replace(/answers\[.+?\]/g, 'answers[' + i + ']')) 
     }); 
     }); 
     } 

</script> 

....

問題型號:

package models; 

import play.data.validation.Constraints; 
import play.db.ebean.Model; 
import javax.persistence.CascadeType; 
import javax.persistence.Entity; 
import javax.persistence.Id; 
import javax.persistence.OneToMany; 
import java.util.ArrayList; 
import java.util.List; 


@Entity 
public class Question extends Model { 

@Id 
public Long id; 

@Constraints.Required 
public String name; 


@OneToMany(cascade = CascadeType.PERSIST, mappedBy = "question") 
public List<Answer> answers; 

public Question() { 

} 

public Question(String name) { 
    this.name = name; 

} 
} 

答型號:

@Entity 
public class Answer extends Model { 

@Id 
public Long id; 

public boolean addRight; 
public boolean editRight; 
public boolean delRight; 
public boolean viewRight; 

@ManyToOne 
public Question question; 

public Answer() { 
} 

public Answer(boolean addRight,boolean editRight,boolean delRight,boolean viewRight, 
Question question) { 
    this.addRight = addRight; 
    this.editRight = editRight; 
    this.delRight = delRight; 
    this.viewRight = viewRight; 
    this.question = question; 
} 
} 

終於控制器節省部分:

public static Result submit() { 
    Form<Question> filledForm = questionForm.bindFromRequest(); 

    if(filledForm.hasErrors()) { 
     User user = User.findByUserName("samuel"); 
     return badRequest(question.render(filledForm)); 
    } 
    else { 
     // If we dont have any errors, we should be around here :) 
     Question question = filledForm.get(); 
     // Since Answer needs reference to Question and with new Question 
     // it cant get it loaded from DB we need to do little dirty trick here 
     // in order to save new question id instantly to answers foreign_key 
     // as question_id, otherwise it will be null 
     System.out.println("-->" + question.answers.size()); 
     if(question.answers != null) { 
      ArrayList<Answer> answersCopy = new ArrayList<Answer>(); 
      Logger.trace("Size of Anwsers : " +answersCopy.size()); 
      for(Answer answer : question.answers) { 
       answersCopy.add(new     
    Answer(answer.addRight,answer.editRight,answer.delRight,answer.viewRight,question)); 
       System.out.println("##" + answer.addRight); 
      } 
      question.answers = answersCopy; 
     } 
     question.save(); 
     return ok("Nice, all saved!"); 

    } 
} 

與上面的代碼我沒有得到任何異常,但..提問部分節省留下Anwser後面。

感謝

+0

它的實際答案不是Anwser,我會先改變這是正確的在每個地方(包括數據庫表名);但順便說一句。你使用Logger.info()來檢查嗎?或System.out.println();或類似的,你從模板到Java端的答案?在調用Ebean.save(問題)之前; ? – 2013-03-07 10:32:45

+0

它好嗎,其他信息? – 2013-03-11 06:29:11

+1

下班後我可以測試一下,如果還沒有人回答,請回報。 – 2013-03-11 06:49:05

回答

2

嗯,我想我懂了工作使用JPA,我有點不確定你是否想與JPA或者只是Ebean做它,但是我覺得你和其他人能夠將它移植了Ebean太。 (我還可以,如果你需要,我猜;)

這裏去的東西我JPA嘗試:

  • 打開終端(或CMD),然後導航到項目稱爲play-2.1.0/samples/java/forms
  • 然後(以防萬一)運行這些命令:play clean .. play compile .. play eclipse
  • 轉到Eclipse和導入有(右擊Package Explorer中 - >現有的項目..)
  • 打開了conf/application.conf並添加(或去掉註釋)這些行:
db.default.driver=org.h2.Driver 
db.default.url="jdbc:h2:mem:play" 
db.default.jndiName=DefaultDS 
jpa.default=defaultPersistenceUnit 
  • 創建的conf/evolutions/default文件夾結構和conf/META-INF
  • 添加一個名爲persistence.xml文件,內容如下:

http://java.sun.com/ xml/ns/persistence/persistence_2_0.xsd「 version =」2。0" >

<persistence-unit name="defaultPersistenceUnit" transaction-type="RESOURCE_LOCAL"> 
    <provider>org.hibernate.ejb.HibernatePersistence</provider> 
    <non-jta-data-source>DefaultDS</non-jta-data-source> 
    <properties> 
     <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/> 
    </properties> 
</persistence-unit> 
</persistence> 
  • 現在,讓我們爲您的答案和題款表,創建文件1.sqlevolutions/default有以下內容:
# --- !Ups 

create table question (
    id      bigint not null, 
    name      varchar(255), 
    constraint pk_question primary key (id)) 
; 

create table answer (
    id      bigint not null, 
    name      varchar(255), 
    question_id    bigint, 
    constraint pk_answer primary key (id)) 
; 

create sequence answer_seq start with 1000; 
create sequence question_seq start with 1000; 

alter table answer add constraint fk_answer_question_1 foreign key (question_id) references question (id) on delete restrict on update restrict; 

# --- !Downs 

SET REFERENTIAL_INTEGRITY FALSE; 

drop table if exists question; 
drop table if exists answer; 

SET REFERENTIAL_INTEGRITY TRUE; 

drop sequence if exists question_seq; 
drop sequence if exists answer_seq; 
  • 修改或添加以下型號:
package models; 

import javax.persistence.Entity; 
import javax.persistence.GeneratedValue; 
import javax.persistence.GenerationType; 
import javax.persistence.Id; 
import javax.persistence.SequenceGenerator; 
import javax.persistence.ManyToOne; 

import play.data.validation.Constraints.Required; 

@Entity 
@SequenceGenerator(name = "answer_seq", sequenceName = "answer_seq") 
public class Answer { 

@Id 
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "answer_seq") 
public Long id; 

@Required 
public String name; 

@ManyToOne 
public Question question; 

public Answer() { 
} 

public Answer(String name, Question question) { 
     this.name = name; 
     this.question = question; 
} 

} 

...

package models; 

import java.util.List; 
import javax.persistence.CascadeType; 
import javax.persistence.Entity; 
import javax.persistence.GeneratedValue; 
import javax.persistence.GenerationType; 
import javax.persistence.Id; 
import javax.persistence.OneToMany; 
import javax.persistence.SequenceGenerator; 
import play.data.validation.Constraints.Required; 
import play.db.jpa.*; 

@Entity 
@SequenceGenerator(name = "question_seq", sequenceName = "question_seq") 
public class Question { 

@Id 
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "question_seq") 
public Long id; 

@Required 
public String name; 

@Valid 
@OneToMany(cascade = CascadeType.PERSIST, mappedBy = "question") 
public List<Answer> answers; 

public Question() { 

} 

public Question(String name) { 
     this.name = name; 
} 

public void save() { 

     JPA.em().persist(this); 

     List<Question> allQuestions = JPA.em().createQuery("from Question order by name").getResultList(); 

     System.out.println("Number of questions: " + allQuestions.size()); 

     for(Question q : allQuestions) { 

      System.out.println("Question --- id: " + q.id + ", name: " + q.name); 

       if(q.answers != null) { 

        for(Answer a : q.answers) { 
          System.out.println("Answer --- id: " + a.id + ", name: " + a.name + " question_id: " + a.question.id); 
        } 
      } 
     } 

} 

} 
  • 好了,現在模型OK,讓我們創建仍然控制器和視圖測試了這一點,從routes文件開始:
# Question 
GET  /questions     controllers.Questions.blank() 
POST /questions     controllers.Questions.submit() 
  • 然後添加以下控制器:
package controllers; 

import static play.data.Form.form; 
import java.util.ArrayList; 
import models.Answer; 
import models.Question; 
import play.data.Form; 
import play.db.jpa.Transactional; 
import play.mvc.Controller; 
import play.mvc.Result; 
import views.html.question.*; 

public class Questions extends Controller { 

/** 
* Defines a form wrapping the Question class. 
*/ 
final static Form<Question> questionForm = form(Question.class); 

/** 
* Display a blank form. 
*/ 
public static Result blank() { 
    return ok(form.render(questionForm)); 
} 

@Transactional 
public static Result submit() { 

Form<Question> filledForm = questionForm.bindFromRequest(); 

if(filledForm.hasErrors()) { 
    return badRequest(form.render(filledForm)); 
} else { 

// If we dont have any errors, we should be around here :) 
Question question = filledForm.get(); 

// Since Answer needs reference to Question and with new Question 
// it cant get it loaded from DB we need to do little dirty trick here 
// in order to save new question id instantly to answers foreign_key 
// as question_id, otherwise it will be null 
if(question.answers != null) { 
    ArrayList<Answer> answersCopy = new ArrayList<Answer>(); 
    for(Answer answer : question.answers) { 
    answersCopy.add(new Answer(answer.name, question)); 
} 
question.answers = answersCopy; 
} 
question.save(); 

// You can also use this test code to save data 
// Question question = new Question("What is your favorite color?"); 
// question.answers = new ArrayList<Answer>(); 
// question.answers.add(new Answer("Blue", question)); 
// question.answers.add(new Answer("Red", question)); 
// question.save(); 

return ok("Nice, all saved!"); 

} 
} 

} 
  • 好,還是一個視圖中去,在views.question名創建它作爲form.scala.html(順便說一句,我重用了應用程序已經用於聯繫的類似代碼秒,但使它與您的機型工作)
@(questionForm: Form[Question]) 

@import helper._ 
@import helper.twitterBootstrap._ 

@title = { 
    Add a new question 
} 

@answerField(field: Field, className: String = "answer") = { 
    @input(field, '_label -> "Answer", '_class -> className) { (id, name, value, _) => 
    <input type="text" name="@name" value="@value"> 
    <a class="removeAnswer btn danger">Remove</a> 
} 
} 

@main(title, nav = "question") { 

@if(questionForm.hasErrors) { 
    <div class="alert-message error"> 
     <p><strong>Oops</strong> Please fix all errors</p> 
    </div> 
} 

@helper.form(action = routes.Questions.submit, 'id -> "form") { 

<fieldset> 
<legend>Fill a question with answers</legend> 

@inputText(
    questionForm("name"), 
    '_label -> "Name of a question" 
) 

<div class="answers"> 

@repeat(questionForm("answers"), min = 0) { answer => 
    @answerField(answer("name")) 
} 

@** 
* Keep an hidden block that will be used as template for Javascript copy code 
* answer_template is only css style to make it hidden (look main.css and declare your own answer_template at bottom) 
**@ 
@answerField(
    questionForm("answers[x].name"), 
    className = "answer_template" 
) 

<div class="clearfix"> 
<div class="input"> 
    <a class="addAnswer btn success">Add answer</a> 
</div> 
</div> 

</div> 
</fieldset> 

<div class="actions"> 
<input type="submit" class="btn primary" value="Insert"> 
<a href="@routes.Application.index" class="btn">Cancel</a> 
</div> 

} 

<script type="text/javascript" charset="utf-8"> 

$('.removeAnswer').live('click', function(e) { 
    var answers = $(this).parents('.answers'); 
    $(this).parents('.answer').remove(); 
    renumber(answers); 
}); 

$('.addAnswer').live('click', function(e) { 
    var answers = $(this).parents('.answers'); 
    var template = $('.answer_template', answers); 
    template.before('<div class="clearfix answer">' + template.html() + '</div>'); 
    renumber(answers); 
}); 

$('#form').submit(function() { 
    $('.answer_template').remove() 
}); 

// -- renumber fields 
// This is probably not the easiest way to do it. A jQuery plugin would help. 

var renumber = function(answers) { 
$('.answer').each(function(i) { 
    $('input', this).each(function() { 
     $(this).attr('name', $(this).attr('name').replace(/answers\[.+?\]/g, 'answers[' + i + ']')) 
     }); 
    }); 
} 

</script> 
} 
  • 作爲最後的調試,檢查你還記得它來編輯文件的main.css最後一行:
.phone_template, .profile_template, .answer_template { 
    display: none; 
} 
  • 並添加main.scala.html這樣的:
<li class="@("active".when(nav == "question"))"> 
    <a href="@routes.Questions.blank()">Questions</a> 
</li> 
  • 現在,如果你還沒有這樣做,去你的瀏覽器,確認要運行的變陣並導航到問題的觀點,並循着提交形成不同的問題和價值觀。

您應該看到在玩遊戲終端窗口結果(與我相似,其正下方),並且如果多數民衆贊成的情況下,你剛纔保存的成功新問題有幾個答案,你可以重複它,只要你喜歡 - 應該工作因爲總是生成新的ID。如果你希望你的表單也包含編輯等,我建議檢查JPA在play samples文件夾(computer-database-jpa)中的使用方式,因爲這個例子已經變得太大了;我可能會在晚些時候把它扔給github,晚安&歡呼聲。

Number of questions: 1 
Question --- id: 50000, name: What is your favorite color? 
Answer --- id: 50000, name: Blue question_id: 50000 
Answer --- id: 50001, name: Red question_id: 50000 
+0

我真的很感謝你的時間..這看起來不錯..但我的問題是,當我嘗試從我的Scala模板發佈相同代碼'@repeat(questionForm(「anwsers」),min = 0){anwserField => @inputText(anwserField) }'..同時讓我試試你的anwser ..如果有任何與模板kindly更新:) ..cheers !!!!!! – 2013-03-11 19:58:01

+0

是的,我也可以嘗試,但如果映射工程從模板傳遞值創建這種模型不應該是一個問題 - 我編輯時,它的工作。 – 2013-03-11 20:01:49

+0

謝謝你..將更新ü在一段時間..直到然後.. 1 :) :) – 2013-03-12 16:58:57

相關問題