Menurut saya, Anda hampir bekerja melawan JSF dan cara kerjanya dalam contoh kode Anda. Sebelum menunjukkan kepada Anda contoh kerja, ada beberapa hal yang ingin saya sampaikan di sini terkait dengan praktik yang baik:
- Jangan memanggil metode secara langsung, gunakan terjemahan referensi properti bawaan. Referensi ke
data.locked
akan diterjemahkan menjadi panggilan ke data.isLocked()
secara otomatis. Panggilan ke data.locked
lebih disukai, karena akan menyebabkan kerangka kerja mengevaluasinya alih-alih Anda mengirimkan nilai yang sudah dievaluasi.
- Bekerja dengan JSF - bukan menentangnya. Ada banyak id yang tidak perlu dan penggunaan tag dan indeks yang tidak diperlukan dalam kode contoh Anda. Tetap sederhana dan bekerja dengan kerangka kerja. Daripada mereferensikan id, mereferensikan objek secara langsung - ini menyederhanakan kode dan membuatnya lebih mudah digunakan pada halaman itu sendiri.
- Gunakan tindakan sebagai pelaksana utama logika dan hasil bisnis. Pemroses tindakan dieksekusi sebelumnya dan dapat digunakan untuk mencegat atau menghentikan eksekusi tindakan utama. Oleh karena itu cocok digunakan sebagai langkah validasi sebelum mengeksekusi logika bisnis.
- Tandai acara Anda. Merupakan praktik yang baik untuk menggunakan konvensi penamaan
on<Something>
saat memberi nama metode yang menerima peristiwa pengguna. Ini memungkinkan Anda mengidentifikasinya dengan jelas.
Saya membuat contoh kecil kode Anda (ini menggunakan Lombok dan Apache Commons);
@Data
@Named
@ViewScoped
public class DataListViewBackingBean implements Serializable {
private Entity entity;
private Entity selectedEntity;
private List<Entity> dataEntities;
@PostConstruct
private void init() {
dataEntities = new ArrayList<>();
for (int i = 0; i < 10; i++) {
dataEntities.add(new Entity(i, RandomUtils.nextBoolean(),
RandomStringUtils.randomAlphabetic(30)));
}
}
@Data
@AllArgsConstructor
@EqualsAndHashCode(exclude = {"locked","description"})
public class Entity {
private int id;
private boolean locked;
private String description;
}
public void onEdit(Entity entity) {
selectedEntity = entity;
}
public void onDelete(Entity entity) {
dataEntities.remove(entity);
selectedEntity = null;
}
}
Kode di atas menginisialisasi daftar data sepuluh entitas dan mengisinya dengan data acak. Saya mengambil hak istimewa untuk mengubah data
menjadi entity
. Mengenai kode HTML Anda, saya merasa perlu dibersihkan. Definisi JSF akan terlihat seperti ini;
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:p="http://primefaces.org/ui">
<h:head>
<title>Data list test</title>
</h:head>
<h:body>
<h:form id="items">
<p:dataList type="definition" value="#{dataListViewBackingBean.dataEntities}" var="entity">
<div class="ui-g">
<div class="ui-g-8">
#{entity.description}
</div>
<div class="ui-g-4" style="text-align: right">
<p:commandButton value="Edit" disabled="#{entity.locked}" action="#{dataListViewBackingBean.onEdit(entity)}" update=":edit" />
<p:commandButton value="Delete" disabled="#{entity.locked}" action="#{dataListViewBackingBean.onDelete(entity)}" update="@form :edit" />
</div>
</div>
</p:dataList>
</h:form>
<h:form id="edit">
<p:outputPanel rendered="#{dataListViewBackingBean.selectedEntity != null}">
<h1>Editing...</h1>
<p:inputText placeholder="Description" value="#{dataListViewBackingBean.selectedEntity.description}" />
<p:commandButton value="Save" update=":items" />
</p:outputPanel>
</h:form>
</h:body>
</html>
Perhatikan bagaimana pengeditan div/outputPanel
dibungkus dalam wadah lain (formulir). Jika kita melewatkan pembungkusan dan malah mendorong pembaruan pada wadah yang dibungkus secara langsung, tag rendered
wadah tersebut tidak akan pernah diperbarui selama penyegaran dan oleh karena itu div tidak akan pernah muncul. Dalam kasus khusus ini, inilah sebabnya formulir didefinisikan di luar wadah, bukan di dalam.
Contoh ini menggunakan kacang @ViewScoped
, jadi selama Anda tetap berada di halaman tersebut, data pendukungnya akan tetap sama. Jika Anda memuat ulang halaman, Anda akan mendapatkan kumpulan data baru dengan entitas baru, karena ini akan menginisialisasi ulang backing bean dan memanggil @PostConstruct
lagi.
Lihat juga
person
Adam Waldenberg
schedule
11.01.2019
edit_{data.id}
. Mungkin ini masalahnya. Apakah Anda mendapatkan pesan kesalahan? Jika Anda memerlukan id hanya untukupdate=
Anda harus meletakkan<span
dan<p:panelGrid
di dalam<h:panelGroup id='edit_#{data.id}'>
dan menghapus idnya. - person Holger   schedule 10.01.2019<h:panelGroup id='edit_#{data.id}'>
dan tidak ada orang lain yang harus mendapatkan id yang sama. - person Holger   schedule 10.01.2019Cannot find component for expression "edit_1" referenced from "main:j_idt70:0:j_idt122".
Pernyataan pembaruan mencari edit_1 tetapi id panelgrid dihasilkan oleh Primefaces: main:j_idt70:0:edit_. Tapi saya ingin panelGrid memiliki id yang sama --› edit_1 sebagai contoh. - person JohnRamb0r   schedule 10.01.2019:0
Anda tidak perlu menggunakan id dinamis. Cukup gunakan yaitueditbox
. Itu akan diubah menjadimain:j_idt70:x:editbox
di mana x adalah indeks baris dari dataList. Seorang kerabatupdate='editbox'
tanpa:
harus menemukannya. - person Holger   schedule 10.01.2019update="editbox"
maka setiap kotak edit akan muncul - Benar kan? - person JohnRamb0r   schedule 10.01.2019