Struts 1 - 迭代中的迭代 - 内行方法

时间:2016-04-03 11:32:39

标签: java iteration form-submit struts-1

我在logic:iterate中有一个logic:iterate。我可以编辑此表中的所有字段。对于每个logic:iterate,我都有一个getXXX行方法。

首先,我点击我的'添加'按钮。迭代充满了3个人。 首先有一个地址,第二个有两个,第三个有三个。 (在实际应用中它是动态的)

现在我更改了一些输入字段,然后点击我的发送按钮。现在调用行方法来初始化旧状态。但是我如何实现行地址方法呢?它只会被调用三次,但我必须填写人员字段并将其取回,或者?

希望它能像上一个帖子一样更好地描述我的问题。

修改 尝试更好地解释它。我有一个人名单,并且在我的getRowPerson-方法中没有问题,因为“索引”仅来自此列表。但是现在我在这个例子中有三个地址列表,我无法将哪个“列表”调用getRowAdress。 (此时我必须使用正确的索引从正确的人那里返回一个地址,但我不知道该人只在地址列表中的位置)

如果getRowAdress在person类中,它也是不同的,但它从未调用过。

另一个问题是getRowAdress只被调用了三次,在我看来,我应该为每个地址行项调用一次。对我的例子六次。我认为内部迭代有问题。我尝试了嵌套:迭代,但也不起作用。

控制台:

adress index2<br>
adress index1<br>
adress index0<br>
person index1<br>
person index2<br>
person index0<br>

HTML 的:     

<logic:iterate id="rowPerson" name="iterateForm" indexId="rowIndex" property="persons" >
    <html:text name="rowPerson" property="name" indexed="true"/>
    <logic:iterate id="rowAdress" name="rowPerson" indexId="rowAdressIndex" property="address" >
        <html:text name="rowAdress" property="addressname" indexed="true"/>
    </logic:iterate>
    <br>
</logic:iterate>
<html:submit value="Send" property="submitvalue"/>
<html:submit value="Add" property="submitvalue"/>
</html:form>

操作

public class HelloWorldAction extends Action {

    @Override
    public ActionForward execute(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response) throws Exception {
        HelloWorldForm helloWorldForm = (HelloWorldForm) form;
        String submitvalue = request.getParameter("submitvalue");
        if (submitvalue == null) {
            return mapping.findForward("success");
        } else if ("Add".equals(submitvalue)) {
            for (int i = 0; i < 3; i++) {
                PersonForm person = new PersonForm();
                person.setName("Person " + i);
                for(int y = 0 ; y <= i ; y++){
                    AddressForm add = new AddressForm();
                    add.setAddressname("Adress" + y);
                    person.getAddress().add(add);
                }
                helloWorldForm.getPersons().add(person);
            }                   

        }
        return mapping.findForward("success");
    }
}

的ActionForm

public class HelloWorldForm extends ActionForm{
    private static final long serialVersionUID = -473562596852452021L;

    private List<PersonForm> persons = new ArrayList<>();

    public PersonForm getRowPerson(int index){      
        System.out.println("person index" + index);
        while(persons.size() <= index){
            persons.add(new PersonForm());
        }           
        return persons.get(index);
    }

    public AddressForm getRowAdress(int index){
        System.out.println("adress index" + index);
        // ???? dont know ???
        return new AddressForm();
    }

    public List<PersonForm> getPersons() {
        return persons;
    }

    public void setPersons(List<PersonForm> persons) {
        this.persons = persons;
    }
}

Personform和Addressform只有setter&amp;吸气剂

1 个答案:

答案 0 :(得分:1)

您的JSP正在呈现此HTML代码:

<input type="text" name="rowPerson[0].name" value="Person 0">    
<input type="text" name="rowAdress[0].addressname" value="Adress0">

这会触发getRowPerson(0)getRowAdress(0)HelloWorldForm的来电。但我们实际上想要嵌套元素,为此我们必须使用nested标记库:

<nested:iterate property="persons">
    <nested:text property="name"/>
    <nested:iterate property="address">
        <nested:text property="addressname"/>
    </nested:iterate>
    <br>
</nested:iterate>

这会产生:

<input type="text" name="persons[0].name" value="Person 0">
<input type="text" name="persons[0].address[0].addressname" value="Adress0">

使用相同的方法读取和写入列表简化了解决方案。如果您的操作中的scope设置为session,这是默认值,那么您的表单将在您提交后覆盖值,而您无需担心动态增长列表。你可以简单地拥有:

public class HelloWorldForm extends ActionForm{
    private List<PersonForm> persons = new ArrayList<>();

    public List<PersonForm> getPersons() {
        return persons;
    }
    public void setPersons(List<PersonForm> persons) {
        this.persons = persons;
    }
}

否则,如果您的操作映射中有scope="request",则在struts-config.xml中,您需要动态重新创建列表。为此,一个选项是使用commons-collection LazyList

public class HelloWorldForm extends ActionForm {
    private final Factory personFactory = new Factory() {
        @Override public Object create() { return new PersonForm(); }
    };
    // commons-collection 4 offers a LazyList<E> with generics
    private List lazyPersons = LazyList.decorate(new ArrayList(), personFactory);

    public List<PersonForm> getPersons() {
        return lazyPersons;
    }
    public void setPersons(List<PersonForm> persons) {
        this.lazyPersons = LazyList.decorate(persons, personFactory);
    }
}

(为PersonForm实现上面的代码)

需要动态增长的列表是一个常见的Struts问题。 如果您想进一步阅读,请参阅以下解决方案目录:http://wiki.apache.org/struts/StrutsCatalogLazyList