2013-04-04 3 views
0

Ниже приводится мой requirement- enter image description hereПользовательские область видимости ManagedBean в JSF2.0 с PrimeFaces 3,5

Здесь у меня есть p:panelGrid, который может добавить & удалить строку таблицы. В сетке содержится p:inputText и различные другие компоненты PrimeFaces вместе с компонентом p:fileUpload в каждой строке. Компонент p:fileUpload установлен с атрибутами mode="advanced" auto="true", который автоматически загружает файл и скрывается после завершения успешной загрузки.

Все p:panelGrid находится в @ViewScoped, отсюда работаю хорошо. Я сохранил p:fileUpload компонент в @RequestScoped, так как для каждого запроса на загрузку он должен загрузить файл, но после добавления новой строки предыдущее состояние больше не сохраняется. поэтому p:fileUpload начинает видимо и в предыдущих строках. Этого я не хочу. Нужно ли мне писать какие-либо настраиваемые области? Ниже представлен вид - |

<h:form> 
    <p:panel id="agentForm" header="#{msg.AGENTS_INFORMATION}" 
     style="overflow:auto; margin-bottom: 2px"> 
     <div align="center" style="margin-top: 20px; margin-bottom: 2px"> 
      <ui:repeat value="#{agent.scenarioList}" var="c"> 
       <p:panelGrid> 
        <p:row> 
         <p:column> 
          <p:inputText id="ipaddress" value="#{c.machineIpAddress}" 
           style="width:90%"> 
           <p:watermark for="ipaddress" value="#{msg.MACHINE_IP_ADDRESS}" /> 
          </p:inputText> 
         </p:column> 
         <p:column> 
          <p:inputText id="username" value="#{c.machineUsername}" 
           style="width:90%"> 
           <p:watermark for="username" value="#{msg.MACHINE_USERNAME}" /> 
          </p:inputText> 
         </p:column> 
         <p:column> 
          <p:password id="passwd" value="#{c.machinePassword}"> 
           <p:watermark for="passwd" value="#{msg.MACHINE_PASSWORD}" /> 
          </p:password> 
         </p:column> 
         <p:column id="fileUpload"> 
          <p:fileUpload rendered="#{!fileUploadController.hidden}" 
           label="Upload Script" style="font-size: 100% !important;" 
           showButtons="false" 
           fileUploadListener="#{fileUploadController.upload}" 
           mode="advanced" auto="true" sizeLimit="100000" 
           allowTypes="/(\.|\/)(py|txt)$/" 
           update="fileUpload, outPanel, :message" /> 
          <p:outputPanel id="outPanel"> 
          <!-- Below outputLabel will be linked to uploaded file, so that User can see the file --> 
          <p:outputLabel style="cursor: pointer" value="View uploded Script" 
            label="View Script" rendered="#{fileUploadController.hidden}" /> 
          </p:outputPanel> 
         </p:column> 
         <p:column> 
          <p:inputText id="testname" value="#{c.testName}" 
           style="width:90%"> 
           <p:watermark for="testname" value="#{msg.TEST_NAME}" /> 
          </p:inputText> 
         </p:column> 
         <p:column> 
          <p:spinner id="threads" value="#{c.threads}" min="1" max="500" 
           size="8"> 
           <p:tooltip for="threads" value="#{msg.TEST_NAME}" 
            showEffect="slide" hideEffect="slide" /> 
          </p:spinner> 
         </p:column> 
         <p:column> 
          <p:selectBooleanCheckbox id="chkSelected" value="#{c.selected}"> 
           <p:tooltip for="chkSelected" value="#{msg.CHECKBOX}" 
            showEffect="slide" hideEffect="slide" /> 
          </p:selectBooleanCheckbox> 
         </p:column> 
        </p:row> 
       </p:panelGrid> 
      </ui:repeat> 
      <p:toolbar style="margin-top: 10px;"> 
       <p:toolbarGroup align="right"> 
        <p:commandButton value="#{msg.ADD_IT}" 
         update=":message, agentForm" 
         actionListener="#{agent.addComponent()}" /> 
        <p:commandButton value="#{msg.DELETE_IT}" 
         update=":message, agentForm" 
         actionListener="#{agent.deleteComponent()}" /> 
       </p:toolbarGroup> 
      </p:toolbar> 
     </div> 
    </p:panel> 
</h:form> 

Мой управляемый компонент, который находится в @ViewScoped выглядеть this-

Объект Сценарий содержит всю информацию о строке. Ниже код-

package org.ravij.performance.model; 
import java.io.Serializable; 
public class Scenario implements Serializable { 
    private String machineIpAddress; 
    private String machineUsername; 
    private String machinePassword; 
    private String uploadedFilePath; 
    private String testName; 
    private int threads = 1; 
    private boolean selected = false; 

    //Below are the getters and setter w.r.t all the above variables 
    //I am not putting it, to make the code short 
} 

Управляемый боб FileUploadController в @RequestScoped

ответ

1

Вы должны просто держать свой атрибут hidden с другими значениями в вашем @ViewScoped боба. В вашем текущем коде есть один атрибут hidden, который используется всеми вашими <p:fileUpload компонентами, которые, вероятно, не то, что вы хотите.

Поведение выглядит хорошо, потому что вы обновляете текущий fileUpload, но согласно вашему коду все остальные компоненты <p:fileUpload должны быть скрыты.

Вы должны также положить ваши <h:form в вашу <ui:repeat, так что вы можете знать текущую строку, которая, затрагиваемой загружаемого файла, поставив что-то вроде индекса (который вы можете получить от <ui:repeat используя varStatus атрибут) или любой другой идентификатор для соответствия текущей строке в скрытом входе.

От #{fileUploadController.upload} самым простым способом, чтобы получить скрытый параметр, чтобы получить ответ от FacesContext, как описано здесь: How to get parametrs to BackingBean from jsf page in <ui:repeat>

UPDATE

Это было немного сложнее, чем ожидалось, проблема заключается в том, что <p:fileUpload отправит все в прилагаемой форме (не пытался играть с атрибутом process), и поэтому будет трудно узнать, в какой строке это проблема с загрузкой файла.

Также я не знал, что вы не могли поставить <h:form в свой <ui:repeat, но поведение вашей кнопки удаления блокируется, так как оно ожидает получить все в одной форме.

Я сделал рабочие ДОУ с помощью диалогового окна, чтобы поставить FileUpload снаружи, вот как:

тривиальное Scenario.java:

public class Scenario implements Serializable { 

    private String machineIpAddress; 
    private String machineUsername; 
    private String machinePassword; 
    private String uploadedFilePath; 
    private String testName; 
    private int threads = 1; 
    private boolean selected = false; 
    private boolean hidden = false; // This is new 

    // + Getters/Setters 
} 

Несколько изменений в AgentInfo.java:

@ManagedBean(name = "agent") 
@ViewScoped 
public class AgentInfo implements Serializable { 

    private List<Scenario> scenarioList; 

    private Scenario currentScenario; // This is new 

    // I removed the @PostConstruct which I rarely use 

    public void addComponent() { 
     if (this.scenarioList != null) { 
      this.scenarioList.add(new Scenario()); 
     } 
    } 

    public void deleteComponent() { 
     if (this.scenarioList == null) { 
      return; 
     } 

     List<Scenario> itemsToDelete = new ArrayList<Scenario>(); 

     for (Scenario scenario : this.scenarioList) { 
      if (scenario.isSelected()) { 
       itemsToDelete.add(scenario); 
      } 
     } 

     this.scenarioList.removeAll(itemsToDelete); 
    } 

    // This is new, it must be called before opening the upload dialog 
    // in order to keep a pointer on the current scenario you are working on 
    public void prepareUpload(Scenario scenario) { 
     this.currentScenario = scenario; 
    } 

    // I put the upload method here 
    public void upload(FileUploadEvent event) { 
     // Do what you need to do here 
     this.currentScenario.setHidden(true); 
     RequestContext.getCurrentInstance().execute("uploadDialogWidget.hide()"); 
    } 

    public List<Scenario> getScenarioList() { 
     if (this.scenarioList == null) { 
      this.scenarioList = new ArrayList<Scenario>(); 
      this.scenarioList.add(new Scenario()); 
     } 

     return scenarioList; 
    } 

    public void setScenarioList(List<Scenario> scenarioList) { 
     this.scenarioList = scenarioList; 
    } 

    public Scenario getCurrentScenario() { 
     return currentScenario; 
    } 

    public void setCurrentScenario(Scenario currentScenario) { 
     this.currentScenario = currentScenario; 
    } 
} 

Большинство изменений в представлении, я положил <h:commandButton, чтобы открыть диалоговое окно в форме. Я также добавил диалоговое окно и добавил атрибут redisplay для ваших полей пароля (которые необходимо иметь, если вы хотите сохранить значение после отправки формы). Обратите внимание, что я удалил ссылки на компонент с message идентификатором, который не был указан, не забудьте снова его ввести. .xhtml,:

<h:form id="agentForm"> 
    <p:panel header="#{msg.AGENTS_INFORMATION}" 
     style="overflow:auto; margin-bottom: 2px"> 
     <div align="center" style="margin-top: 20px; margin-bottom: 2px"> 
      <ui:repeat value="#{agent.scenarioList}" var="c"> 
       <p:panelGrid> 
        <p:row> 
         <p:column> 
          <p:inputText id="ipaddress" value="#{c.machineIpAddress}" 
           style="width:90%"> 
           <p:watermark for="ipaddress" value="#{msg.MACHINE_IP_ADDRESS}" /> 
          </p:inputText> 
         </p:column> 
         <p:column> 
          <p:inputText id="username" value="#{c.machineUsername}" 
           style="width:90%"> 
           <p:watermark for="username" value="#{msg.MACHINE_USERNAME}" /> 
          </p:inputText> 
         </p:column> 
         <p:column> 
          <p:password id="passwd" value="#{c.machinePassword}" redisplay="true"> 
           <p:watermark for="passwd" value="#{msg.MACHINE_PASSWORD}" /> 
          </p:password> 
         </p:column> 
         <p:column id="fileUpload"> 
          <p:commandButton icon="ui-icon-arrowthick-1-n" value="Upload" 
              actionListener="#{agent.prepareUpload(c)}" 
              update=":uploadDialog" 
              oncomplete="uploadDialogWidget.show()" 
              rendered="#{!c.hidden}" /> 
          <p:outputPanel id="outPanel"> 
          <!-- Below outputLabel will be linked to uploaded file, so that User can see the file --> 
          <p:outputLabel style="cursor: pointer" value="View uploded Script" 
            rendered="#{c.hidden}" /> 
          </p:outputPanel> 
         </p:column> 
         <p:column> 
          <p:inputText id="testname" value="#{c.testName}" 
           style="width:90%"> 
           <p:watermark for="testname" value="#{msg.TEST_NAME}" /> 
          </p:inputText> 
         </p:column> 
         <p:column> 
          <p:spinner id="threads" value="#{c.threads}" min="1" max="500" 
           size="8"> 
           <p:tooltip for="threads" value="#{msg.TEST_NAME}" 
            showEffect="slide" hideEffect="slide" /> 
          </p:spinner> 
         </p:column> 
         <p:column> 
          <p:selectBooleanCheckbox id="chkSelected" value="#{c.selected}"> 
           <p:tooltip for="chkSelected" value="#{msg.CHECKBOX}" 
            showEffect="slide" hideEffect="slide" /> 
          </p:selectBooleanCheckbox> 
         </p:column> 
        </p:row> 
       </p:panelGrid> 
      </ui:repeat> 
      <p:toolbar style="margin-top: 10px;"> 
       <p:toolbarGroup align="right"> 
        <p:commandButton value="#{msg.ADD_IT}" update="agentForm" 
            actionListener="#{agent.addComponent()}" /> 
        <p:commandButton value="#{msg.DELETE_IT}" update="agentForm" 
         actionListener="#{agent.deleteComponent()}" /> 
       </p:toolbarGroup> 
      </p:toolbar> 
     </div> 
    </p:panel> 
</h:form> 
<p:dialog id="uploadDialog" widgetVar="uploadDialogWidget" header="File upload"> 
    <h:form rendered="#{!empty agent.currentScenario}"> 
     <p:fileUpload 
      label="Upload Script" style="font-size: 100% !important;" 
      showButtons="false" 
      fileUploadListener="#{agent.upload}" 
      mode="advanced" auto="true" sizeLimit="100000" 
      allowTypes="/(\.|\/)(py|txt)$/" 
      update=":agentForm"> 
     </p:fileUpload> 
     <p:commandButton value="Cancel" onclick="uploadDialogWidget.hide();" onstart="return false;" /> 
    </h:form> 
</p:dialog> 

Вы должны рассмотреть, чтобы перейти от <p:panelGrid к <p:dataTable который имеет встроенный механизм для работы с выбором строки.

+0

Спасибо ... Не могли бы вы подробнее рассказать о скрытых полях в '@ ViewScoped' bean. Мой bean 'содержит' список объекта 'user'. Это традиционно и достаточно просто. Можете ли вы предоставить модифицированный код на основе моего представления? –

+0

Несомненно, добавьте код 'addComponent()' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' из '' 'вашего агента в ваш вопрос, и я обновлю свой ответ на рабочий пример. –

+0

Обновлен вопрос с помощью требуемого кода. Пожалуйста, изучите его. –

Смежные вопросы