在grails中处理来自动态表单的参数以实现一对多关系 [英] Handling parameters from dynamic form for one-to-many relationships in grails

查看:97
本文介绍了在grails中处理来自动态表单的参数以实现一对多关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的主要问题是在一个动态表单中管理一对多关系时处理pramas地图,以及在编辑/更新域对象时处理一对多的最佳实践动态形式。我的问题的输入如下。



我设法破解了一个表单,允许我在一个Dynamic表单中创建下面显示的域对象,因为存在在创建电话号码并将其分配给联系人的单独表单中没有任何意义,只需在我的应用程序中以一种形式创建所有内容即可。我设法实现了类似于我在上一个问题(感谢帮助过的人)

  class Contact {

字符串firstName
字符串lastName
// ....
//其他一些属性
// ...

static hasMany = [手机:手机]
$静态映射= {
电话排序:索引,cascade:全删除孤儿
}
}

类电话{
int index
字符串数字
字符串类型
联系人联系人
$ b $ static belongsTo = [联系人:联系人]
}

我基本上设法从'params'映射获取值,并自己解析它们并手动创建域对象和关联。即我没有使用与默认脚手架相同的逻辑,即

 联系人c =新联系人(params)

etc ....,我只是穿过所有的参数,手工制作我的域对象,并保存它们,一切正常。



我的控制器的代码块看起来像这样(这是剥离下来,只是为了显示一个点)

 //通过手工输入参数值创建联系人
def cntct = new Contact()
cntct.firstName = params.firstName
cntct.lastName = params .lastName
// etc ...

//获取数字值的数组,类型
def numbers = params ['phone.number']
def types = params ['phone.type']

//通过一个数组循环并创建手机
numbers.eachWithIndex(){num,i - >
//从
def phone = new Phone()
phone.number = num
phone.type = types [i]
phone创建手机域对象。 index = i
cntct.addToPhones(phone)
}

//保存

我的问题如下:


  • 处理这种情况的最佳做法是使用Command对象在这种情况下工作,如果是的话我可以在哪里找到关于这方面的更多信息,我在搜索过程中发现的所有例子都是一对一的关系,我无法找到一对一的例子吗? / li>
  • 在这种情况下,处理手机关系的最佳方式是在编辑联系人对象时添加/删除手机。我的意思是创建逻辑很简单,因为我必须总是在保存时创建新手机,但在处理更新联系人时,用户可能已经删除了手机和/或编辑正在退出的手机和/或添加了一些新手机。现在我所做的只是删除联系人所拥有的所有电话,并根据表单发布的内容重新创建它们,但我认为这不是最好的方式,我也不认为现有的并与发布的值进行比较,并做手动差异是做到这一点的最佳方式,是否有最佳做法如何处理这个?



谢谢,希望问题很清楚。

[edit]只需要更多信息,就可以使用javascript(jquery)动态添加和删除手机信息。在表单中[/ edit]

解决方案

声明:我不知道使用grails时以下方法是否有效。



请参阅更好的动态表单方式。作者说:


要添加LineItems,我有一些js计算新的索引并将其添加到DOM。在删除LineItem 时,我必须重新编号所有索引,这是我想要避免的内容


所以我做了什么

我有一个存储下一个索引的变量

  var nextIndex = 0; 

当页面被加载时,我执行一个JavaScript函数来计算该集合有多少个子项并进行配置nextIndex变量。您可以使用JQuery或YUI。



静态添加一个孩子



我创建了一个存储模板的变量(注意 {index}

  var child = < DIV>中
+ =< div>
+ =< label>名称< / label>
+ =< input type =textname = \childList [{index}]。name \/>
+ =< / div>
+ =< / div>

当用户点击添加孩子按钮时,我将 {index} - 通过使用正则表达式 - 通过存储在nextIndex变量中的值并递增1。然后,我添加到DOM



另请参阅使用Javascript动态添加和删除HTML元素



添加小孩

在这里您可以看到Paolo Bergantino解决方案



删除



但我认为这是删除时长大的问题。无论您删除多少个孩子,都不会触及nextIndex变量。看到这里

  / ** 
* var nextIndex = 3;
* /

< input type =textname =childList [0] .name/>
< input type =textname =childList [1] .name/> //将被删除
< input type =textname =childList [2] .name/>

假设我删除了 childList 1 我做了什么?我应该重新编号所有的索引吗?

在服务器端我使用AutoPopulatingList。由于childList 1 已被删除,AutoPopulatingList 将其作为空。因此,在初始化过程中我做了

  List< Child> childList = new AutoPopulatingList(new ElementFactory(){
public Object createElement(int index)throws ElementInstantiationException {
/ **
*删除添加的任何空值
* /
childList.removeAll(Collections.singletonList(null));

return new Child();
}
});

通过这种方式,我的集合只包含两个子元素(没有任何空值)和不需要在客户端对所有索引重新编号



关于添加/删除,您可以看到 link 在这里我展示了一个可以给你一些见解的场景。

另请参阅 Grails UI插件

My main question here is dealing with the pramas map when having a one-to-many relationship managed within one dynamic form, as well as best practices for dealing with one-to-many when editing/updating a domain object through the dynamic form. The inputs for my questions are as follows.

I have managed to hack away a form that allows me to create the domain objects shown below in one Dynamic form, since there is no point in having a separate form for creating phone numbers and then assigning them to a contact, it makes sense to just create everything in one form in my application. I managed to implement something similar to what I have asked in my Previous Question (thanks for the people who helped out)

class Contact{

    String firstName
    String lastName
    // ....
    // some other properties
    // ...

    static hasMany = [phones:Phone]
    static mapping = {
        phones sort:"index", cascade: "all-delete-orphan"
    }
}

class Phone{
    int index
    String number
    String type
    Contact contact

    static belongsTo = [contact:Contact]
}

I basically managed to get the values from the 'params' map and parse them on my own and create the domain object and association manually. I.e. i did not use the same logic that is used in the default scaffolding, i.e.

Contact c = new Contact(params)

etc...., i just looped through all the params and hand crafted my domain objects and saved them and everything works out fine.

My controller has code blocks that look like this (this is stripped down, just to show a point)

//create the contact by handpicking params values
def cntct = new Contact()
cntct.firstName = params.firstName
cntct.lastName = params.lastName
//etc...

//get array of values for number,type
def numbers = params['phone.number']
def types =  params['phone.type']

//loop through one of the arrays and create the phones
numbers.eachWithIndex(){ num, i ->
    //create the phone domain object from 
    def phone = new Phone()
    phone.number = num
    phone.type = types[i]
    phone.index = i
    cntct.addToPhones(phone)
}

//save

My questions are as follows:

  • What is the best practice of handeling such a situation, would using Command objects work in this case, if yes where can i found more info about this, all the examples I have found during my search deal with one-to-one relationships, I couldn't find an example for one-to-many?
  • What is the best way to deal with the relatiohsips of the phones in this case, in terms of add/removing phones when editing the contact object. I mean the creation logic is simple since I have to always create new phones on save, but when dealing with updating a contact, the user might have removed a phone and/or editing an exiting one and/or added some new phones. Right now what I do is just delete all the phones a contact has and re-create them according to what was posted by the form, but I feel that's not the best way to do it, I also don't think looping over the existing ones and comparing with the posted values and doing a manual diff is the best way to do it either, is there a best practice on how to deal with this?

Thanks, hopefully the questions are clear.

[edit] Just for more information, phone information can be added and deleted dynamically using javascript (jquery) within the form [/edit]

解决方案

disclaimer: i do not know if the following approach works when using grails. Let me know later.

See better way for dynamic forms. The author says:

To add LineItems I have some js that calculates the new index and adds that to the DOM. When deleting a LineItem i have to renumber all the indexes and it is what i would like to avoid

So what i do

I have a variable which stores the next index

var nextIndex = 0;

When the page is loaded, i perform a JavaScript function which calculates how many child The collection has and configure nextIndex variable. You can use JQuery or YUI, feel free.

Adding a child statically

I create a variable which store the template (Notice {index})

var child   = "<div>"
           +=     "<div>"
           +=         "<label>Name</label>"
           +=         "<input type="text" name=\"childList[{index}].name\"/>"
           +=     "</div>"
           += "</div>"

When the user click on the Add child button, i replace {index} - by using regex - by the value stored in the nextIndex variable and increment by one. Then i add to the DOM

See also Add and Remove HTML elements dynamically with Javascript

Adding a child dinamically

Here you can see The Paolo Bergantino solution

By removing

But i think it is the issue grow up when deleting. No matter how many child you remove, does not touch on the nextIndex variable. See here

/**
  * var nextIndex = 3;
  */

<input type="text" name="childList[0].name"/>
<input type="text" name="childList[1].name"/> // It will be removed
<input type="text" name="childList[2].name"/>

Suppose i remove childList1 What i do ??? Should i renumber all the indexes ???

On the server side i use AutoPopulatingList. Because childList1 has been removed, AutoPopulatingList handles it as null. So on the initialization i do

List<Child> childList = new AutoPopulatingList(new ElementFactory() {
   public Object createElement(int index) throws ElementInstantiationException {
       /**
         * remove any null value added
         */    
       childList.removeAll(Collections.singletonList(null));

       return new Child();
   }
});

This way, my collection just contains two child (without any null value) and i do not need to renumber all the indexes on the client side

About adding/removing you can see this link where i show a scenario wich can gives you some insight.

See also Grails UI plugin

这篇关于在grails中处理来自动态表单的参数以实现一对多关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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