在我的应用程序中,我有一个可以管理整个软件的超级用户。 当记录的用户是管理员时,他可以看到一些按钮(管理)。
问题出在这个按钮之一,管理按钮,当他被解雇时,他必须显示一个隐藏的div并在他内部加载几个按钮。 当我单击“管理”按钮时,他只加载div,如果我再次单击它,则加载其余代码(按钮)并获取阻塞。
我认为DOM.getElementById("center_top").getStyle().setDisplay(Display.BLOCK);
会阻止其他代码,我需要再次单击才能加载按钮。
以下是该方法的代码:
package com.unibo.questionandanswer.client.view;
import java.util.List;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Style.Display;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.unibo.questionandanswer.client.CategoriesInterface;
import com.unibo.questionandanswer.client.QuestionAndAnswer;
import com.unibo.questionandanswer.client.UsersService;
import com.unibo.questionandanswer.client.UsersServiceAsync;
import com.unibo.questionandanswer.shared.User;
import com.unibo.questionandanswer.shared.UserRights;
/**
*
* @author Dario
*
*/
public class AdminController {
UserRights rightsFilter = UserRights.USER;
private final UsersServiceAsync usersService = GWT
.create(UsersService.class);
private QuestionAndAnswer controller;
public AdminController(CategoriesInterface categorie) {
if (categorie instanceof QuestionAndAnswer) {
this.controller = (QuestionAndAnswer) categorie.getController();
}
amministraSito();
}
@SuppressWarnings("deprecation")
private void amministraSito() {
// Bottone per l'admin gestione software
final Button amministra = new Button("Amministra");
final Button sitoNormale = new Button("Q&A Sito");
RootPanel.get("top_header").add(amministra);
RootPanel.get("top_header").add(sitoNormale);
DOM.setElementAttribute(amministra.getElement(), "id",
"amministraButton");
DOM.setElementAttribute(sitoNormale.getElement(), "id",
"backSitoButton");
/**
* Esce dalla modalità amministra
*/
sitoNormale.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
controller.setSelectedImpostaCat(false);
amministra.setEnabled(true);
sitoNormale.setEnabled(false);
Window.Location.reload();
}
});
/**
* Entra in modalità amministra
*/
amministra.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
// RootPanel.get("center").clear();
// DOM.getElementById("center_top").getStyle().setDisplay(Display.BLOCK);
Document.get().getElementById("center_top").getStyle()
.setDisplay(Display.BLOCK);
RootPanel.get("center_top").clear();
// Util per promuovere giudici o rimuoverli
giudiceUtil();
// Util per rimuovere una risposta
removeAnswerUtil();
// Util per rimuovere una domanda
removeQuestionUtil();
// Util per modificare le categorie
mangeTreeUtil();
amministra.setEnabled(false);
sitoNormale.setEnabled(true);
}
});
}
/**
* Metodo che permette all'admin di modificare le categorie
*/
private void mangeTreeUtil() {
// Bottone per l'admin gestione software
final Button manageTree = new Button("Imposta categorie");
RootPanel.get("center_top").add(manageTree);
manageTree.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
RootPanel.get("center").clear();
controller.setSelectedImpostaCat(true);
controller.buildAdminTree();
}
});
}
/**
* Metodo che permette all'admin di rimuovere una domanda
*/
private void removeQuestionUtil() {
}
/**
* Metodo che permette all'admin di rimuovere una risposta
*/
private void removeAnswerUtil() {
}
/**
* Metodo che permette all'admi di selezionare un giudice o rimuoverlo
*/
private void giudiceUtil() {
// Bottone per inviare dati login al server-side
final Button showUsers = new Button("All Users");
RootPanel.get("center_top").add(showUsers);
showUsers.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
controller.setSelectedImpostaCat(false);
showAllRegisterdUsers();
}
});
}
/**
* Metodo che motra tutti gli utenti registrati
*/
private void showAllRegisterdUsers() {
usersService.registeredUsers(new AsyncCallback<List<User>>() {
@Override
public void onFailure(Throwable caught) {
String alert = "Errore in fase di registrazione";
for (StackTraceElement el : caught.getStackTrace())
alert += "\n" + el.toString();
Window.alert(alert);
}
@Override
public void onSuccess(List<User> result) {
RootPanel.get("center").clear();
final Button users = new Button("Users");
final Button giudici = new Button("Giudici");
HorizontalPanel buttonFilter = new HorizontalPanel();
buttonFilter.add(users);
buttonFilter.add(giudici);
RootPanel.get("center").add(buttonFilter);
// Codice HTML che spiega il funzionamento del come fare
HorizontalPanel hp = new HorizontalPanel();
HTML html = new HTML(
"<p style='margin-left: 20px'>Selezionare il nome utente per cambiare i suoi diritti da USER a GIUDICE e viceversa!</p><hr>");
hp.add(html); // adds the widget to the panel
RootPanel.get("center").add(hp);
users.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
rightsFilter = UserRights.USER;
showAllRegisterdUsers();
controller.setSelectedImpostaCat(false);
}
});
giudici.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
rightsFilter = UserRights.GIUDICE;
showAllRegisterdUsers();
controller.setSelectedImpostaCat(false);
}
});
for (User curr : result) {
if (curr.get_userRight().equals(rightsFilter)) {
// Label per il dialog promozione a giudice
final Label textDialogGiud = new Label(
"Promuovere l'utente a Giudice?");
// Label per il dialog declassa a user
final Label textDialogGiudRemove = new Label(
"Declassare l'utente a User?");
// Bottone per promuovere user
final Button promuovi = new Button("Promuovi!");
// Bottone per declassare user
final Button declassa = new Button("Declassa!");
// Bottone per chiudere la dialog
final Button closeWindow = new Button("Chiudi");
// promuovi.getElement().setId("promuoviUser");
closeWindow.getElement().setId("chiudiDialog");
HorizontalPanel lineDialogText = new HorizontalPanel();
HorizontalPanel controllButtonsDialog = new HorizontalPanel();
FlowPanel flowPanelGiudice = new FlowPanel();
// Se l'utente selezionato è giudice carico i pulsanti
// per declassare
if (curr.get_userRight().equals(UserRights.GIUDICE)) {
controllButtonsDialog.add(declassa);
lineDialogText.add(textDialogGiudRemove);
} else if (curr.get_userRight().equals(UserRights.USER)) {
// Se l'utente selezionato è user carico i pulsanti
// per promuovere
controllButtonsDialog.add(promuovi);
lineDialogText.add(textDialogGiud);
}
// lineDialogText.add(textDialogGiud);
// controllButtonsDialog.add(promuovi);
controllButtonsDialog.add(closeWindow);
// Carico gli horizontal panel con i label e button che
// mi servono
// in base allo user
flowPanelGiudice.add(lineDialogText);
flowPanelGiudice.add(controllButtonsDialog);
final DialogBox dialogSelectGiud = new DialogBox();
dialogSelectGiud.setAnimationEnabled(true);
dialogSelectGiud.setWidget(flowPanelGiudice);
final HorizontalPanel userPanel = new HorizontalPanel();
final Label username = new Label(curr.getUsername());
// Handler che gestisce la gestione del click sulla
// lista
// di utenti o giudici
username.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
dialogSelectGiud.setText("Selezionato: "
+ username.getText().toString());
dialogSelectGiud.center();
dialogSelectGiud.show();
}
});
userPanel.add(username);
RootPanel.get("center").add(userPanel);
/*
* BUTTON PROMUOVI UTENTE
*/
promuovi.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
dialogSelectGiud.hide();
usersService.findUser(username.getText()
.toString(), new AsyncCallback<User>() {
@Override
public void onFailure(Throwable caught) {
Window.alert("Errore nel trovare lo User!");
}
@Override
public void onSuccess(User result) {
result.set_userRight(UserRights.GIUDICE);
usersService.changeUserRights(result,
new AsyncCallback<Void>() {
@Override
public void onFailure(
Throwable caught) {
Window.alert("Errore nella promozione utente!");
}
@Override
public void onSuccess(
Void result) {
Window.alert("Utente promosso a giudice! "
+ username
.getText()
.toString());
showAllRegisterdUsers();
}
});
}
});
}
});
/*
* BUTTON DECLASSA UTENTE
*/
declassa.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
dialogSelectGiud.hide();
usersService.findUser(username.getText()
.toString(), new AsyncCallback<User>() {
@Override
public void onFailure(Throwable caught) {
Window.alert("Errore nel trovare lo User!");
}
@Override
public void onSuccess(User result) {
result.set_userRight(UserRights.USER);
usersService.changeUserRights(result,
new AsyncCallback<Void>() {
@Override
public void onFailure(
Throwable caught) {
Window.alert("Errore nel declassare l'utente!");
}
@Override
public void onSuccess(
Void result) {
Window.alert("Utente declassato a user! "
+ username
.getText()
.toString());
showAllRegisterdUsers();
}
});
}
});
}
});
/*
* BUTTON CHIUDI DIALOG PROMOZIONE
*/
closeWindow.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
dialogSelectGiud.hide();
}
});
/*
* QUALCHE CSS PER BUTTONS
*/
userPanel.getElement().setAttribute("style",
"margin: auto; padding: 10px");
users.getElement().setAttribute("style",
"margin: 5px 0 5px 5px;");
giudici.getElement().setAttribute("style",
"margin: 5px 0 5px 5px; ");
//CSS per bottoni dentro dialogbox
controllButtonsDialog.setWidth("100%");
controllButtonsDialog.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
promuovi.getElement().setAttribute("style",
"margin: 20px 5px 5px 5px; float: left;");
declassa.getElement().setAttribute("style",
"margin: 20px 5px 5px 5px; float: left;");
closeWindow.getElement().setAttribute("style",
"margin: 20px 5px 5px 5px; float: right;");
}
}
}
});
}
}
这里隐藏“center_top”div的css
#center_top{
position: absolute;
top: 0;
width: 100%;
height: 30px;
border-bottom:1px solid black;
display: none;
}
为什么只有这个按钮我需要双击show div并在里面加载按钮?
DOM.getElementById是否阻止了代码的执行?
浏览器控制台取消了这行代码
/**
* Adds a widget to the detach list. This is the list of widgets to be
* detached when the page unloads.
*
* <p>
* This method must be called for all widgets that have no parent widgets.
* These are most commonly {@link RootPanel RootPanels}, but can also be any
* widget used to wrap an existing element on the page. Failing to do this may
* cause these widgets to leak memory. This method is called automatically by
* widgets' wrap methods (e.g.
* {@link Button#wrap(com.google.gwt.dom.client.Element)}).
* </p>
*
* <p>
* This method may <em>not</em> be called on any widget whose element is
* contained in another widget. This is to ensure that the DOM and Widget
* hierarchies cannot get into an inconsistent state.
* </p>
*
* @param widget the widget to be cleaned up when the page closes
* @see #detachNow(Widget)
*/
public static void detachOnWindowClose(Widget widget) {
assert !widgetsToDetach.contains(widget) : "detachOnUnload() called twice "
+ "for the same widget";
assert !isElementChildOfWidget(widget.getElement()) : "A widget that has "
+ "an existing parent widget may not be added to the detach list";
widgetsToDetach.add(widget);
}
答案 0 :(得分:1)
因此,在将分组添加到分离列表时会出现错误。
首先,您需要知道分离列表是什么。它在detachOnWindowClose
方法的注释中进行了解释。我会尝试以更简单的方式解释这一点。
每当您使用页面上显示的窗口小部件时,窗口小部件都会创建一个DOM(Document Object Model)结构并与之相连。例如,窗口小部件具有事件处理程序的代码。 GWT需要保持对该连接的控制,因此当删除DOM时(例如,页面被清除或卸载 - 通常分离),它可以释放先前所述事件处理程序(或其他资源)使用的内存)。否则可能导致内存泄漏。
当小部件没有父窗口小部件时,必须将其添加到分离列表
RootPanel.get().add(widget);
或仅RootPanel.get("element_id");
)直接将小部件添加到DOM时Panel.wrap(element);
)其他窗口小部件中包含的窗口小部件由父窗口小部件分离。
如果在向分离列表添加小部件时出错,则可能意味着您满足以下两个条件之一:
您需要知道,当您调用RootPanel.get("center_top");
时,您实际上正在使用与带有center_top
id的DOM元素连接的RootPanel小部件。这意味着下次调用RootPanel.get("center_top");
时会出现错误,因为它已经在分离列表中。此外,如果使用RootPanel.get(id);
元素中包含的元素的id调用center_top
,您也会收到错误,因为它已经有RootPanel.get("center_top");
的第一次调用创建的父窗口小部件方法
我希望你现在能够了解分离清单是什么,我也希望我不会因为这种简化的解释而被投票;)
现在让我们回到你的问题。我想是其中之一
giudiceUtil();
,removeAnswerUtil();
,removeQuestionUtil();
或mangeTreeUtil();
方法符合上述提出错误的条件。
您可以重复使用先前通话创建的RootPanel
(不要使用相同的ID两次调用RootPanel.get()
)或以自下而上的顺序创建它们(这意味着首先你得到一个子元素的RootPanel然后是父元素。)
干杯!