2017-05-30 92 views
0

我在Custom UISelectOne組件中遇到問題。我的目的是創建包含自己數據的新自定義組件。所以我創建了組件的costactor方法中的虛擬數據訪問,如下所示。當我把控件放在XHTML文件中時,它在第一次加載時工作正常,但是當我點擊HTML頁面的subbmit按鈕時會出現錯誤併發出警告。錯誤和警告消息如下所示;JSF自定義UISelectOne回發錯誤;驗證錯誤:值無效

順便說一句,我看到了一些類似的問題。但他們中沒有一個是關於定製控制的,我無法解決我的問題。正如我所說我想要在組件自己的承包商中加載數據。所以我認爲我的情況看起來不一樣。

) WARNING: FacesMessage(s) have been enqueued, but may not have been displayed. sourceId=j_idt6:j_idt7[severity=(ERROR 2), summary=(j_idt6:j_idt7: Validation Error: Value is not valid), detail=(j_idt6:j_idt7: Validation Error: Value is not valid)]

所以我的控制和格式化器代碼:

@Named("ABankAccountList") 
@RequestScoped 
@FacesComponent(createTag = true, namespace = "http://abank.com.tr/example", tagName = "ABankAccountList", value = "com.abank.customcontrols.ABankAccountList") 
public class ABankAccountList extends UISelectOne { 



    private List<Account> accounts; 

    public ABankAccountList() { 

     this.setConverter(new AccountConverter()); 
     accounts=new ArrayList<Account>(); 
     Account tempAcc = null; 
     for (int i = 5; i < 8; i++) { 
      tempAcc = new Account(); 
      tempAcc.setAccountId(i); 
      tempAcc.setAccountNumber(i + "0456-789"); 
      tempAcc.setCurrencyCode("TRY"); 
      tempAcc.setIbanNumber("TR-" + i + "-98583213213223"); 
      accounts.add(tempAcc); 

     } 

    } 

    public List<Account> getAccounts() { 
     return accounts; 
    } 

    public void setAccounts(List<Account> accounts) { 
     this.accounts = accounts; 
    } 

    // After POST Back 
    @Override 
    public void decode(FacesContext context) { 


     super.decode(context); 


    } 

    @Override 
    public void encodeBegin(FacesContext context) throws IOException { 

     if (context.isPostback()) 
     { 
      return ; 

     } 

     UISelectItems selectItems = new UISelectItems(); 

     List<SelectItem> result = new ArrayList<SelectItem>(); 
     try { 

      for (Account account : accounts) { 
       SelectItem item = new SelectItem(account, account.getAccountNumber()); 
       result.add(item); 

      } 

     } catch (Exception e) { 
      // log.error("Failed to create enum list", e); 
     } 


     getChildren().clear(); 

     selectItems.setValue(result); 
     getChildren().add(selectItems); 






    } 

    // Render HTML 
    @Override 
    public void encodeEnd(FacesContext context) throws IOException { 


     super.encodeEnd(context); 
    } 



} 

另外我有如下一個Convertet類。 當我調試代碼時,我注意到postBak後getAsObject方法觸發兩次。我不確定這是否正常?

@FacesConverter(value = "AccountConverter") 
public class AccountConverter implements Converter 
{ 

    @Override 
    public Object getAsObject(FacesContext context, UIComponent uiComponent, String arg2) 
    { 

     ValueExpression vex = context.getApplication().getExpressionFactory() .createValueExpression(context.getELContext(),  
       "#{ABankAccountList}", ABankAccountList.class); 

     ABankAccountList contoller = (ABankAccountList)vex.getValue(context.getELContext()); 
     Account rAccount=null; 
     for (Account acc : contoller.getAccounts()) { 
       if (arg2.toString().equals(acc.getAccountId().toString())) { 
        rAccount = acc; 
       } 
      }   

      return rAccount; 
    } 

    @Override 
    public String getAsString(FacesContext arg0, UIComponent arg1, Object account) { 
     Account accctemp=((Account)account); 
     Integer accid=accctemp.getAccountId(); 
     return accid.toString(); 

    } 

} 

其實我不知道我應該在哪裏加載數據和whreer應該設置Converter類。我明白的是;問題是因爲回發之前和之後的數據匹配。但我不知道該怎麼辦?

最好的問候。

回答

0

嗨,我找到了解決方案。我已經覆蓋了Value Class的equals方法。

@Override 
    public boolean equals(Object obj) { 
     if (obj == null) 
      return false; 
     if (obj instanceof Account) 
     { 
      Account other = (Account) obj; 
      if (other.getAccountId() == this.getAccountId() 
       && other.getIbanNumber() == this.getIbanNumber()  
        ) 
       return true; 
     } 
     return false; 
    }