2013-05-04 51 views
0

我的小門面板ProductViews的列表(SELECT)
product list by categories
你選擇你的ProductView從SELECT後,通過ProductView中的ID到細節,從數據庫中其負載的產品形式。您可以修改產品實體,並在完成後保存它。
details form

保存後,我嘗試刷新SELECT列表以更新其數據,但它不起作用(例如,在重命名後,SELECT包含產品的舊名稱,但是當我選擇相同的ProductView時,它再次將實體重新加載到細節表單中,當然新數據從數據庫中出現)我不想重新加載產品列表,我想從內存中解決它。下面是我的源:檢票SELECT不更新它的模型

的ProductView:

@Entity 
@Table(name = "product") 
@XmlRootElement 
public class ProductView implements Serializable{ 

     private static final long serialVersionUID = 1L; 
     @Id 
     @GeneratedValue(strategy = GenerationType.IDENTITY) 
     @Basic(optional = false) 
     @Column(name = "id") 
     private Long id; 
     @Column(name = "name") 
     private String name; 
     @Enumerated(EnumType.ORDINAL) 
     @Column(name = "category") 
     private Category category; 

     public ProductView() { 
     } 
     public ProductView(Long id) { 
      this.id = id; 
     } 
     public ProductView(Product product) { 
      this.id = product.getId(); 
      this.name = product.getName(); 
      this.category = product.getCategory(); 
     } 
     // + getters & setters 
    } 

產品:

@Entity 
@Table(name = "product") 
@XmlRootElement 
public class Product implements Serializable { 
    // same as ProductView but more data, objects, connections, etc 
} 

和Wicket面板與評論

private Product product; 
private ProductView productView; 
private List<ProductView> productViews; 

private Form productForm; 
private Select categorySelectComponent; 
private WebMarkupContainer contentContainer; 

public ProductPanel(String id) { 
    super(id); 
    setOutputMarkupId(true); 

    add(contentContainer = new WebMarkupContainer("contentContainer")); // container DIV 
    contentContainer.setOutputMarkupId(true); // refreshable 
    contentContainer.add(productForm = new Form("productForm")); // details FORM 
    contentContainer.add(categorySelectComponent = new Select("categorySelectComponent", new PropertyModel<ProductView>(this, "productView"))); // item SELECT 

    categorySelectComponent.add(new SelectOptions<ProductView>(// first category 
      "oneCategory", 
      new PropertyModel<List<ProductView>>(this, "oneProducts"), // see getOneProducts(); list of productviews 
      new IOptionRenderer<ProductView>() { 
       @Override 
       public String getDisplayValue(ProductView p) { 
        return p.getName(); 
       } 
       @Override 
       public IModel<ProductView> getModel(ProductView p) { 
        return new Model<ProductView>(p); 
       } 
      })); 
    categorySelectComponent.add(new SelectOptions<ProductView>(// second category 
      "twoCategory", 
      new PropertyModel<List<ProductView>>(this, "twoProducts"), // see getTwoProducts(); 
      new IOptionRenderer<ProductView>() { 
       @Override 
       public String getDisplayValue(ProductView p) { 
        return p.getName(); 
       } 
       @Override 
       public IModel<ProductView> getModel(ProductView p) { 
        return new Model<ProductView>(p); 
       } 
      })); 
    categorySelectComponent.add(new SelectOptions<ProductView>(// third category 
      "threeCategory", 
      new PropertyModel<List<ProductView>>(this, "threeProducts"), // see getThreeProducts(); 
      new IOptionRenderer<ProductView>() { 
       @Override 
       public String getDisplayValue(ProductView p) { 
        return p.getName(); 
       } 
       @Override 
       public IModel<ProductView> getModel(ProductView p) { 
        return new Model<ProductView>(p); 
       } 
      })); 

    categorySelectComponent.add(new OnChangeAjaxBehavior() { // update form after choose entity 
     @Override 
     protected void onUpdate(final AjaxRequestTarget art) { 
      product = getProductFacade().find(productView.getId()); 
      updatePanel(art); 
     } 
    }); 

    productForm.add(
     // some details component (textfields, radios, links, etc) to edit Product 
    ); 
    productForm.add(new AjaxSubmitLink("formSubmitLink") { // save entity 
     @Override 
     protected void onSubmit(AjaxRequestTarget art, Form<?> form) { 
      super.onSubmit(art, form); // i don't know it is necessary at all 
      getProductFacade().edit(product); 
      updateProductViewInCategoryMap(art); // important method 
      //art.add(contentContainer); //it is in update method 
     } 
    }); 
} 

更多內部面板方法

private Map<Category, List<ProductView>> categoryMap; // all product by categories 
public void initCategoryMap() { 
    categoryMap = new EnumMap<Category, List<ProductView>>(ProductView.class); 
    categoryMap.put(Category.ONE, new ArrayList<ProductView>()); 
    categoryMap.put(Category.TWO, new ArrayList<ProductView>()); 
    categoryMap.put(Category.THREE, new ArrayList<ProductView>()); 

    for (ProductView view : getProductViews()) { 
     categoryMap.get(view.getCategory()).add(view); 
    } 
} 

//***** Get Products By Categories ******* 

final public List<ProductView> getOneProducts(){ 
    if (categoryMap == null){ 
     initCategoryMap(); 
    } 
    return categoryMap.get(Category.ONE); 
} 

final public List<ProductView> getTwoCategory(){ 
    if (categoryMap == null){ 
     initCategoryMap(); 
    } 
    return categoryMap.get(Category.TWO); 
} 

final public List<ProductView> getThreeProducts(){ 
    if (categoryMap == null){ 
     initCategoryMap(); 
    } 
    return categoryMap.get(Category.THREE); 
} 

// ************************************** 

public List<ProductView> getProductViews() { // Get All Product 
    if (productViews == null) { 
     productViews = getProductFacade().findAllProductAsView(); 
    } 
    return productViews; 
} 

private void updatePanel(AjaxRequestTarget art) { // refresh panel 
    art.add(ProductPanel.this); 
} 

private void updateProductViewInCategoryMap(AjaxRequestTarget art) { // change Product in map after save (call from onSubmit method of AjaxSubmitLink) 
    for(Map.Entry<Category, List<ProductView>> entry : categoryMap.entrySet()){ // search category contains entity 
     if (entry.getValue().contains(productView)){ 
      entry.getValue().remove(productView); // remove entity from category 
      break; 
     } 
    } 
    productView = new ProductView(product); // new productview by modified product 
    categoryMap.get(productView.getCategory()).add(productView); // add entity to it's category's list 
    art.add(contentContainer); 
} 

和HTML:

<select class="categorySelect" wicket:id="categorySelectComponent"> 
    <optgroup label="Category One"> 
     <wicket:container wicket:id="oneCategory"> 
       <option wicket:id="option"></option> 
      </wicket:container> 
    </optgroup> 
    <optgroup label="Category Two"> 
     <wicket:container wicket:id="twoCategory"> 
        <option wicket:id="option"></option> 
      </wicket:container> 
    </optgroup> 
    <optgroup label="Category Three"> 
     <wicket:container wicket:id="threeCategory"> 
       <option wicket:id="option"></option> 
      </wicket:container> 
    </optgroup> 
</select> 

任何想法?

+0

單挑,您在onSubmit方法中將contentContainer添加到ART兩次。 – zeratul021 2013-05-04 15:02:53

+0

哦,是的,我把所有的東西強制SELECT更新,但沒有任何幫助。感謝通知,我刪除了雙線。 – Victor 2013-05-04 15:34:51

+0

我做了一個測試項目,如果這有助於[鏈接](http://www.2shared.com/file/2fuIgSib/OptGroupTest.html#) – Victor 2013-05-05 13:26:17

回答

1

呼叫#setRecreateChoices(真)。

+0

你太棒了! – Victor 2013-05-05 19:09:51

1

如何更新productViews保存更改或使用LoadableDetachableModel而不是PropertyModelcategorySelectComponent

這裏:在所有SelectOptions

new Select("categorySelectComponent", new PropertyModel<ProductView>(this, "productView") 
+0

是的,我可以更新名稱例如,但如果類別更改?我必須將實體移動到另一個列表。 – Victor 2013-05-04 16:47:15