Istnieją trzy tabele w bazie danych MySQL, category
, sub_category
i brand
(producent) gdzie category
jest dominującym tj spoczynku sub_category
i brand
. Mam nadzieję, że związek między menu może być bardziej przejrzysty w oparciu o relacje na stole.Resetowanie dziecko p: selectOneMenus wewnątrz AP: DataTable do pusta, kiedy wybrany jest oznaczony element w ich liście dominującej
Wszystkie trzy <p:selectOneMenu>
S są umieszczone wewnątrz <p:dataTable>
w trzech odpowiednich kolumnach zidentyfikowane przez <p:column>
. Ignoruję wszystkie niedogodności dla zwięzłości.
row
odpowiada JPA zarządzanego podmiotu będącego product
w tym przypadku określone przez var="row"
w <p:dataTable>
związany.
To jest rzeczywisty znak zapytania: Po wybraniu elementu (pierwszy) o wartości null
w categoryList
(rodzica), jego dziecko wymienia subCategoryList
i brandList
reszta powinna być pusty.
Kategoria Lista: Lista
<p:selectOneMenu id="categoryList"
value="#{row.category}"
required="#{param['javax.faces.source'] ne component.clientId}">
<f:selectItem itemLabel="Select"
itemValue="#{null}"/>
<!-- When this item is selected, its children below should be reset to empty. -->
<f:selectItems var="category"
value="#{productManagedBean.categories}"
itemLabel="Select"
itemValue="#{category}"/>
<p:ajax update="subCategoryList brandList"/>
<!-- The listener functionality is left incomplete here. -->
</p:selectOneMenu>
Podkategoria:
<p:selectOneMenu id="subCategoryList"
value="#{row.subCategory}">
<f:selectItem itemLabel="Select"
itemValue="#{null}"/>
<f:selectItems var="subCategory"
value="#{productManagedBean.getSubCategories(row.category)}"
itemLabel="#{subCategory.subCatName}"
itemValue="#{subCategory}"
rendered="true"/>
</p:selectOneMenu>
Marka (producent) Lista:
<p:selectOneMenu id="brandList"
value="#{row.brand}">
<f:selectItem itemLabel="Select"
itemValue="#{null}"/>
<f:selectItems var="brand"
value="#{productManagedBean.getBrands(row.category)}"
itemLabel="#{brand.brandName}"
itemValue="#{brand}"
rendered="true"/>
</p:selectOneMenu>
zarządzanego fasoli (leniwy model danych może być ignorowane w kontekście tego pytania):
@Named
@ViewScoped
public class ProductManagedBean extends LazyDataModel<Product> implements Serializable {
@Inject
private Service service;
// Associated with <p:selectOneMenu id="categoryList">.
private List<Category> categories; // Getter & setter.
// These are merely helper maps to reduce possible database calls.
private Map<Category, List<SubCategory>> subCategoriesByCategory;
private Map<Category, List<Brand>> brandByCategory;
public ProductManagedBean() {}
@PostConstruct
private void init() {
// This can be application scoped somewhere else as per business requirement.
categories = service.getCatgeoryList();
subCategoriesByCategory = new HashMap<Category, List<SubCategory>>();
brandByCategory = new HashMap<Category, List<Brand>>();
}
// This method populates <f:selectItems> associated with <p:selectOneMenu id="brandList">.
public List<SubCategory> getSubCategories(Category category) {
// category is never null here unless something is broken deliberately.
if (category == null) {
return null;
}
List<SubCategory> subCategories = subCategoriesByCategory.get(category);
if (subCategories == null) {
subCategories = service.findSubCategoriesByCategoryId(category.getCatId());
subCategoriesByCategory.put(category, subCategories);
}
return subCategories;
}
// This method populates <f:selectItems> associated with <p:selectOneMenu id="brandList">.
public List<Brand> getBrands(Category category) {
// category is never null here unless something is broken deliberately.
if (category == null) {
return null;
}
List<Brand> brands = brandByCategory.get(category);
if (brands == null) {
brands = service.findBrandsByCategoryId(category.getCatId());
brandByCategory.put(category, brands);
}
return brands;
}
}
W każdym przypadku wybrana wartość w dowolnym z tych menu nie jest dostarczana do odpowiedniego komponentu bean. Jest dostępny tylko w modelu wspieranym przez JPA (odpowiednio: value="#{row.category}"
, value="#{row.subCategory}"
i value="#{row.brand}"
).
► Jak sygnalizować fasoli podkładową, że pierwszy element o wartości null
(oznaczonego „Wybierz”) w menu nadrzędnego jest wybrany tak, aby jego dziecko wymienia resetowania opróżnić? Powinno to nastąpić w dowolny możliwy sposób, jeśli nie jest to wykonalne.
Używam finału PrimeFaces 5.2 (wydanie społecznościowe) i Mojarra 2.2.12.
to nie jest potrzebne, chyba że jest zerowy klucz obcy w tabeli podstawowej bazy konkretnie przy użyciu określonych ON DELETE SET NULL
opcję pozwalającą dostawcy opcjonalnego rodzic w każdej (lub) odpowiedniego rzędu dziecięcej.