2014-01-03 2 views
1

У меня есть <h:dataTable>, который заполняется из класса Entity и отображает разные продукты. Я хочу, чтобы иметь возможность щелкнуть <h:commandLink> и отредактировать строку, к которой принадлежит ссылка. Я структурировал его в основном так же, как этот хороший пример и статья на mkyong.JSF <h:inputText>/<h: outputText> not rendering в соответствии с логическим значением

В таблице (с некоторыми столбцами исключенных):

<h:form> 
    <h:dataTable id="gnomeTable" value="#{gnome.productList}" 
       var="item" 
       styleClass="gnomeTable" 
       headerClass="gnomeTableHeader" 
       rowClasses="gnomeTableOddRow,gnomeTableEvenRow" 
       bgcolor="#F1F1F1" border="10" cellspacing="2" 
       rules="all" >   

     <f:facet name="header"> 
      <h:outputText value="List of available gnomes for sale" /> 
     </f:facet> 

     <h:column> 
      <f:facet name="header"> 
       <h:outputText value="GnomeID" /> 
      </f:facet> 
      <h:outputText value="#{item.id}"></h:outputText> 
     </h:column> 

     <h:column> 
      <f:facet name="header"> 
       <h:outputText value="Name"/> 
      </f:facet> 
      <h:outputText value="#{item.name}" rendered="#{not item.editable}"></h:outputText> 
      <h:inputText value="#{item.name}" rendered="#{item.editable}"></h:inputText> 
     </h:column> 

     <h:column> 
      <f:facet name="header"> 
       <h:outputText value="Available"/> 
      </f:facet> 
      <h:outputText value="#{item.available}" rendered="#{not item.editable}"></h:outputText> 
      <h:inputText value="#{item.available}" rendered="#{item.editable}"></h:inputText> 
     </h:column> 
     <h:column> 
      <f:facet name="header"> 
       <h:outputText value="Edit"/> 
      </f:facet> 
      <h:commandLink value="Edit" action="#{gnome.editAction(item)}" rendered="#{not item.editable}" /> 
     </h:column> 
    </h:dataTable> 
    <h:commandButton value="Save Changes" action="#{gnome.saveAction}" /> 
</h:form> 

Методы Бобовые:

public String saveAction() { 
    for (Gnome g : productList) { 
     g.setEditable(false); 
    } 
    return null; 
} 

public String editAction(Gnome gnome) { 
    gnome.setEditable(true); 
    return null; 
} 

Имущество boolean editable в классе сущностей помечается, как @Transient, так как это не является частью постоянные данные, и я не хочу, чтобы диспетчер организации коснулся его:

@Transient 
private boolean editable; 

Я думал, что это приведет к тому, что переменная boolean будет установлена ​​на значение true при нажатии кнопки «Редактировать», строка переопределяет поля теперь как <h:inputText>, но ничего не происходит. Я отлаживал его и следил за тем, чтобы переменная была установлена ​​в true, а именно.

Я также нашел это SO question, что я подумал, возможно, что-то похожее на проблему, которую я испытываю. Разница в том, что обновление страницы ничего не меняет.

Что мне не хватает?

Edit 1: В первой версии этого вопроса я был по ошибке вставили неверный код. Тот, который включен сейчас, - это мой текущий код, который теоретически должен работать, но это не так.

Edit 2: Инициализация productList, где Gnome является класс сущностей.

private List<Gnome> productList = new ArrayList<>(); 

public List<Gnome> getProductList() { 
    productList = gnomeFacade.findAll(); 
    return productList; 
} 

public void setProductList(List<Gnome> productList) { 
    this.productList = productList; 
} 
+0

Где именно находится ваш h: тег inputText? Я не вижу в столбцах. Вам нужно будет указать как outputText, так и inputText с одним рендерированным значением true, а одно в false в соответствии с editable - true или false. –

+0

@prajeeshkumar вы правы! По ошибке я вставил старую версию кода. Я отредактировал его в правильной версии! –

+0

@ DanielB Вероятно, вы должны удалить этот вопрос, это не имеет никакого смысла в отношении SO, поскольку проблема не может помочь другим людям. Рад, что это работает! –

ответ

2

После тестирования примера, только возможная ошибка в том, что вы используете RequestScoped боб. Чтобы сделать его работу, вам нужно как минимум ViewScoped или SessionScoped. Ortherwise, измененный контент productList теряется при каждом запросе (действие кнопки).

Согласно редактированию, вторая ошибка заключается в том, как данные берутся. Вам нужно загрузить данные в другом месте, чем добытчик, как это:

@PostConstruct 
public void init() 
{ 
    productList = gnomeFacade.findAll(); 
} 

public List<Gnome> getProductList() 
{ 
    return productList; 
} 

Ortherwise, каждые действия вашего список сбрасывается.

+0

Мысль о том, что ошибка может быть связана с чем-то вроде этого, поразила меня, хотя я не мог понять, почему это произошло. Теперь я изменил его на '@ ViewScoped' вместо' @ RequestScoped', так как я хочу, чтобы bean сохранялся до тех пор, пока я не перейду на другую страницу. Хотя проблема все еще остается; логическая переменная имеет значение true, но форма не отображается иначе, чем раньше. –

+0

@ DanielB Можете ли вы показать, как вы инициализируете 'productList'? –

+0

Добавлена ​​инициализация списка в исходном посте, см. Edit 2! –

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