构建具有动态内容的 Vaadin Web 应用程序
Building a Vaadin web app with dynamic content
我正在尝试通过 Vaadin(Vaadin Framework 8)创建网络应用程序。
我阅读了几页文档,但仍然对 Vaadin 应用程序的结构有很大的疑问。我的问题是我对它背后的理论缺乏了解,我将尝试通过第一次尝试代码来揭示我的问题。如果能帮助我理解 Vaadin 的工作原理,我将不胜感激。
我想创建一个用户可以注册、登录和注销的网站。
网站的 GUI 结构是一个 主页,如果用户是未登录,如果用户已登录,而不是登录按钮,它应该出现注销按钮。
首先,我有一个扩展 UI 的 class;在那个 class 中,我设置了 servlet 和 init()
方法。
在 init()
方法中,我开始创建一个 VerticalLayout()
,然后是一个 MenuBar
和一个 Panel
(称为 contentPanel)。然后,我创建一个 Navigator
。我遇到的第一个问题是,我将 Navigator 理解为一种在不同页面之间浏览的可能性; Navigator 的构造函数想要 SingleComponentContainer
,所以现在,我不知道如何在不同的网页之间导航。对于我的示例,在构造函数中我使用面板: new Navigator(this, contentPanel);
然后我添加不同的 View
然后将出现在面板内。最后,我导航到 Welcome
页面。
我的UI class:
public class MyUI extends UI {
/**
* Class that checks if the user is in the database
* and the psw inserted is correct
*/
public static Authentication AUTH;
public static User user = null;
@WebServlet(value = "/*", asyncSupported= true)
@VaadinServletConfiguration(productionMode = false, ui = MyUI.class)
public static class MyUIServlet extends VaadinServlet {
}
@Override
protected void init(VaadinRequest request) {
AUTH = new Authentication();
VaadinSession.getCurrent().setAttribute("user", user);
final VerticalLayout layout = new VerticalLayout();
layout.setMargin(true);
setContent(layout);
Panel contentPanel = new Panel("Main Panel");
contentPanel.setSizeFull();
new Navigator(this, contentPanel);
getNavigator().addView(LoginPage.NAME, LoginPage.class);
getNavigator().setErrorView(LoginPage.class);
getNavigator().addView(LogoutPage.NAME, LogoutPage.class);
getNavigator().addView(WelcomePage.NAME, WelcomePage.class);
MenuBar.Command welcome = new Command() {
@Override
public void menuSelected(MenuItem selectedItem) {
getNavigator().navigateTo(WelcomePage.NAME);
}
};
MenuBar.Command login = new Command() {
@Override
public void menuSelected(MenuItem selectedItem) {
getNavigator().navigateTo(LoginPage.NAME);
}
};
MenuBar.Command logout = new Command() {
@Override
public void menuSelected(MenuItem selectedItem) {
getNavigator().navigateTo(LogoutPage.NAME);
}
};
MenuBar mainMenu = new MenuBar();
mainMenu.addItem("Welcome", VaadinIcons.ARROW_CIRCLE_LEFT, welcome);
mainMenu.addItem("Login", VaadinIcons.ENTER, login);
mainMenu.addItem("Logout", VaadinIcons.EXIT, logout);
layout.addComponent(mainMenu);
layout.addComponent(contentPanel);
getNavigator().navigateTo(WelcomePage.NAME);
}
}
登录页面class:
public class LoginPage extends VerticalLayout implements View {
private static final long serialVersionUID = 1L;
public static final String NAME = "loginpage";
public LoginPage(){
Panel panel = new Panel("Login");
panel.setSizeUndefined();
addComponent(panel);
FormLayout content = new FormLayout();
TextField username = new TextField("Username");
content.addComponent(username);
PasswordField password = new PasswordField("Password");
content.addComponent(password);
Button send = new Button("Enter");
send.addClickListener(new Button.ClickListener() {
private static final long serialVersionUID = 1L;
public void buttonClick(ClickEvent event) {
//The authenticate method will returns
//true if the credentials are correct
//false otherwise
if(MyUI.AUTH.authenticate(username.getValue(), password.getValue())){
//In AUTH there is a User field called "user"
//User is a class that represents an user (so it has mail, psw, name etc)
VaadinSession.getCurrent().setAttribute("user", MyUI.AUTH.getUser());
}else{
Notification.show("Invalid credentials", Notification.Type.ERROR_MESSAGE);
}
}
});
content.addComponent(send);
content.setSizeUndefined();
content.setMargin(true);
panel.setContent(content);
setComponentAlignment(panel, Alignment.MIDDLE_CENTER);
}
}
注销class与登录class结构相同;有一个注销方法:
private void doLogout() {
MyUI.AUTH.setUser(null);
VaadinSession.getCurrent().setAttribute("user", MyUI.AUTH.getUser());
getSession().close();
}
另一个问题是:如何根据用户状态(是否登录?)在我的布局中动态添加组件
下一个问题是:我不明白如何有效地注销。
我将添加完整的代码以方便任何测试。
public class LogoutPage extends VerticalLayout implements View {
private static final long serialVersionUID = 1L;
public static final String NAME = "logoutpage";
public LogoutPage(){
Panel panel = new Panel("Logout");
panel.setSizeUndefined();
addComponent(panel);
Button logout = new Button("Logout");
logout.addClickListener(e -> doLogout());
addComponent(logout);
}
private void doLogout() {
MyUI.AUTH.setUser(null);
VaadinSession.getCurrent().setAttribute("user", MyUI.AUTH.getUser());
getSession().close();
}
}
______________________________________________________________________________
public class WelcomePage extends VerticalLayout implements View {
private static final long serialVersionUID = 1L;
public static final String NAME = "welcomepage";
public WelcomePage() {
setMargin(true);
setSpacing(true);
Label welcome = new Label("Welcome");
welcome.addStyleName("h1");
addComponent(welcome);
}
@Override
public void enter(ViewChangeEvent event) {
}
}
______________________________________________________________________________
public class Authentication {
private static User user = null;
//those fields should be in user; this is just a test
private String userID = "ID";
private String psw = "psw";
public Authentication() {
}
public void setUser(User user) {
Authentication.user = user;
}
public User getUser(){
return Authentication.user;
}
public Boolean authenticate(String userID, String psw){
if(userID == this.userID && psw == this.psw) {
user = new User();
return true;
}
return false;
}
}
我看到很多用户都在为 vaadin 概念苦苦挣扎。
简而言之,它不是基于页面的框架,每次单击鼠标都会切换到新页面。
相反,它更像是一个 Swing 应用程序,您有一个单一的 gui 实例,您可以在其中添加 forms/poups/buttons、修改它们并根据用户交互删除它们。这被称为 Single-Page Application.
导航器主要用于允许用户使用网络浏览器的 backward/forward 按钮导航到 "previous" 页面,或将特定页面添加为书签。
This link 提供了有关此概念的更多详细信息。
回答你的问题:
- 使用单个 page/nvigation
- 未登录时,显示模态登录弹出窗口
- 当用户正确输入认证时,去掉弹窗,竖排显示主要内容
- 当用户注销时,从垂直布局中移除内容
对于您的简单用例,无需使用导航器或视图
我最初 运行 遇到了同样的问题,这让我对 Spring 感兴趣,最终对 Vaadin4Spring 感兴趣。查看 https://github.com/peholmst/vaadin4spring/tree/master/samples/security-sample-managed,即使您 对使用 Spring 没有兴趣。它将为您提供有关视图导航的一些见解,并且通过添加 Vaadin4Spring 侧边栏,它可以轻松控制对视图和菜单的访问。我相信权限很快就会成为您关注的焦点,这可能很复杂。
我正在尝试通过 Vaadin(Vaadin Framework 8)创建网络应用程序。
我阅读了几页文档,但仍然对 Vaadin 应用程序的结构有很大的疑问。我的问题是我对它背后的理论缺乏了解,我将尝试通过第一次尝试代码来揭示我的问题。如果能帮助我理解 Vaadin 的工作原理,我将不胜感激。
我想创建一个用户可以注册、登录和注销的网站。
网站的 GUI 结构是一个 主页,如果用户是未登录,如果用户已登录,而不是登录按钮,它应该出现注销按钮。
首先,我有一个扩展 UI 的 class;在那个 class 中,我设置了 servlet 和 init()
方法。
在 init()
方法中,我开始创建一个 VerticalLayout()
,然后是一个 MenuBar
和一个 Panel
(称为 contentPanel)。然后,我创建一个 Navigator
。我遇到的第一个问题是,我将 Navigator 理解为一种在不同页面之间浏览的可能性; Navigator 的构造函数想要 SingleComponentContainer
,所以现在,我不知道如何在不同的网页之间导航。对于我的示例,在构造函数中我使用面板: new Navigator(this, contentPanel);
然后我添加不同的 View
然后将出现在面板内。最后,我导航到 Welcome
页面。
我的UI class:
public class MyUI extends UI {
/**
* Class that checks if the user is in the database
* and the psw inserted is correct
*/
public static Authentication AUTH;
public static User user = null;
@WebServlet(value = "/*", asyncSupported= true)
@VaadinServletConfiguration(productionMode = false, ui = MyUI.class)
public static class MyUIServlet extends VaadinServlet {
}
@Override
protected void init(VaadinRequest request) {
AUTH = new Authentication();
VaadinSession.getCurrent().setAttribute("user", user);
final VerticalLayout layout = new VerticalLayout();
layout.setMargin(true);
setContent(layout);
Panel contentPanel = new Panel("Main Panel");
contentPanel.setSizeFull();
new Navigator(this, contentPanel);
getNavigator().addView(LoginPage.NAME, LoginPage.class);
getNavigator().setErrorView(LoginPage.class);
getNavigator().addView(LogoutPage.NAME, LogoutPage.class);
getNavigator().addView(WelcomePage.NAME, WelcomePage.class);
MenuBar.Command welcome = new Command() {
@Override
public void menuSelected(MenuItem selectedItem) {
getNavigator().navigateTo(WelcomePage.NAME);
}
};
MenuBar.Command login = new Command() {
@Override
public void menuSelected(MenuItem selectedItem) {
getNavigator().navigateTo(LoginPage.NAME);
}
};
MenuBar.Command logout = new Command() {
@Override
public void menuSelected(MenuItem selectedItem) {
getNavigator().navigateTo(LogoutPage.NAME);
}
};
MenuBar mainMenu = new MenuBar();
mainMenu.addItem("Welcome", VaadinIcons.ARROW_CIRCLE_LEFT, welcome);
mainMenu.addItem("Login", VaadinIcons.ENTER, login);
mainMenu.addItem("Logout", VaadinIcons.EXIT, logout);
layout.addComponent(mainMenu);
layout.addComponent(contentPanel);
getNavigator().navigateTo(WelcomePage.NAME);
}
}
登录页面class:
public class LoginPage extends VerticalLayout implements View {
private static final long serialVersionUID = 1L;
public static final String NAME = "loginpage";
public LoginPage(){
Panel panel = new Panel("Login");
panel.setSizeUndefined();
addComponent(panel);
FormLayout content = new FormLayout();
TextField username = new TextField("Username");
content.addComponent(username);
PasswordField password = new PasswordField("Password");
content.addComponent(password);
Button send = new Button("Enter");
send.addClickListener(new Button.ClickListener() {
private static final long serialVersionUID = 1L;
public void buttonClick(ClickEvent event) {
//The authenticate method will returns
//true if the credentials are correct
//false otherwise
if(MyUI.AUTH.authenticate(username.getValue(), password.getValue())){
//In AUTH there is a User field called "user"
//User is a class that represents an user (so it has mail, psw, name etc)
VaadinSession.getCurrent().setAttribute("user", MyUI.AUTH.getUser());
}else{
Notification.show("Invalid credentials", Notification.Type.ERROR_MESSAGE);
}
}
});
content.addComponent(send);
content.setSizeUndefined();
content.setMargin(true);
panel.setContent(content);
setComponentAlignment(panel, Alignment.MIDDLE_CENTER);
}
}
注销class与登录class结构相同;有一个注销方法:
private void doLogout() {
MyUI.AUTH.setUser(null);
VaadinSession.getCurrent().setAttribute("user", MyUI.AUTH.getUser());
getSession().close();
}
另一个问题是:如何根据用户状态(是否登录?)在我的布局中动态添加组件
下一个问题是:我不明白如何有效地注销。
我将添加完整的代码以方便任何测试。
public class LogoutPage extends VerticalLayout implements View {
private static final long serialVersionUID = 1L;
public static final String NAME = "logoutpage";
public LogoutPage(){
Panel panel = new Panel("Logout");
panel.setSizeUndefined();
addComponent(panel);
Button logout = new Button("Logout");
logout.addClickListener(e -> doLogout());
addComponent(logout);
}
private void doLogout() {
MyUI.AUTH.setUser(null);
VaadinSession.getCurrent().setAttribute("user", MyUI.AUTH.getUser());
getSession().close();
}
}
______________________________________________________________________________
public class WelcomePage extends VerticalLayout implements View {
private static final long serialVersionUID = 1L;
public static final String NAME = "welcomepage";
public WelcomePage() {
setMargin(true);
setSpacing(true);
Label welcome = new Label("Welcome");
welcome.addStyleName("h1");
addComponent(welcome);
}
@Override
public void enter(ViewChangeEvent event) {
}
}
______________________________________________________________________________
public class Authentication {
private static User user = null;
//those fields should be in user; this is just a test
private String userID = "ID";
private String psw = "psw";
public Authentication() {
}
public void setUser(User user) {
Authentication.user = user;
}
public User getUser(){
return Authentication.user;
}
public Boolean authenticate(String userID, String psw){
if(userID == this.userID && psw == this.psw) {
user = new User();
return true;
}
return false;
}
}
我看到很多用户都在为 vaadin 概念苦苦挣扎。
简而言之,它不是基于页面的框架,每次单击鼠标都会切换到新页面。
相反,它更像是一个 Swing 应用程序,您有一个单一的 gui 实例,您可以在其中添加 forms/poups/buttons、修改它们并根据用户交互删除它们。这被称为 Single-Page Application.
导航器主要用于允许用户使用网络浏览器的 backward/forward 按钮导航到 "previous" 页面,或将特定页面添加为书签。
This link 提供了有关此概念的更多详细信息。
回答你的问题: - 使用单个 page/nvigation - 未登录时,显示模态登录弹出窗口 - 当用户正确输入认证时,去掉弹窗,竖排显示主要内容 - 当用户注销时,从垂直布局中移除内容
对于您的简单用例,无需使用导航器或视图
我最初 运行 遇到了同样的问题,这让我对 Spring 感兴趣,最终对 Vaadin4Spring 感兴趣。查看 https://github.com/peholmst/vaadin4spring/tree/master/samples/security-sample-managed,即使您 对使用 Spring 没有兴趣。它将为您提供有关视图导航的一些见解,并且通过添加 Vaadin4Spring 侧边栏,它可以轻松控制对视图和菜单的访问。我相信权限很快就会成为您关注的焦点,这可能很复杂。