在Vaadin 8中,我们可以让用户通过单击与BrowserWindowOpener
关联的按钮,在Web浏览器中打开新的标签/窗口。作为discussed in the manual的一个新UI
代表我们实例化。我们传递的只是一个.class
对象,我们的UI
子类的类将被实例化以显示在新窗口/选项卡中。例如:
BrowserWindowOpener opener = new BrowserWindowOpener( PersonDetailUI.class );
对我有用。我的问题是:如何在新窗口/标签中将一些信息传递给新的UI
对象?
例如,我可能需要通过:
我看到了I asked about this same issue for Vaadin 7。考虑这是Vaadin 8问题的更新版本。唯一的答案推测是有关向新窗口的URI添加参数。但这将我限制为一小段文字。我更喜欢传递一个智能对象,而不是一个哑字符串。
答案 0 :(得分:2)
基本上可以使用三种方法,以及这些方法的组合
使用URI参数。如您所述,这仅限于String
类型的数据。
String uriFragment = Page.getCurrent().getUriFragment();
VaadinRequest.getParameter()
读取URI参数,在主UI的init(...)中将VaadinRequest作为参数给出UI共享相同的Vaadin会话。这提供了一些工具,即
您可以使用会话属性,即VaadinSession.getCurrent().getAttribute(…)
和VaadinSession.getCurrent().setAttribute(…)
如果使用CDI或Spring,则可以注入/自动装配@VaadinSessionScoped
bean。然后,该实例绑定到Session,因此在选项卡之间共享。
从数据库中读取数据(可能使用1.和/或2.作为键的帮助)
答案 1 :(得分:0)
Answer by Tatu隆德提到将URI参数传递给正在打开的新窗口。
这里是Vaadin 8.5.0中一个简单的小演示应用程序,用于演示该技术。
我们从假装从数据库中取回的三只猫开始。每次用户选择一只猫时,我们都会得到该猫的标识符UUID对象。我们生成该UUID的规范的32个字符的十六进制字符串表示形式。并且我们将其指定为要通过参数键cat_id
传递的参数值。我们通过调用BrowserWindowOpener::setParameter
来指定该参数。
请注意,我们是在Grid
列出的猫中选择一个项目时执行的。由于浏览器在打开窗口时的限制,必须在用户单击其按钮之前 配置BrowserWindowOpener
。据我所知,我们无法对单击按钮做出反应来运行代码。
新的浏览器窗口填充有UI的自动实例化的子类。在这种情况下,CatUI
是我们写的。在CatUI
中,我们获得URI参数,提取表示UUID的字符串,重新创建UUID
对象,然后将其传递给我们假装的数据库服务以获取有问题的猫。然后,使用Cat
对象值填充布局的字段。我们不会为数据绑定猫到布局而烦恼,因为这并不是本演示的重点。
注意事项:这只是一个演示,它忽略了与通过URI参数将信息传递到新窗口的问题没有直接关系的问题。例如,并发性的关键问题在这里被忽略了,但是在实际工作中并不会出现。
该演示包含四个类文件,所有文件都粘贴在下面。
MainUI
(在应用启动时默认打开)CatUI
(当用户单击按钮时打开)Cat
(业务对象,具有name
和id
属性)DatabaseService
(假装猫记录的仓库)MainUI
package com.basilbourque.example;
import com.vaadin.annotations.Theme;
import com.vaadin.annotations.VaadinServletConfiguration;
import com.vaadin.server.BrowserWindowOpener;
import com.vaadin.server.VaadinRequest;
import com.vaadin.server.VaadinServlet;
import com.vaadin.ui.Button;
import com.vaadin.ui.Grid;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
import javax.servlet.annotation.WebServlet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
/**
* This UI is the application entry point. A UI may either represent a browser window
* (or tab) or some part of an HTML page where a Vaadin application is embedded.
* <p>
* The UI is initialized using {@link #init(VaadinRequest)}. This method is intended to be
* overridden to add component to the user interface and initialize non-component functionality.
*/
@Theme ( "mytheme" )
public class MainUI extends UI {
private Grid< Cat > grid;
private Button button;
@Override
protected void init ( VaadinRequest vaadinRequest ) {
// Configure button to open now browser window/tab.
this.button = new Button( "Open in new window" );
BrowserWindowOpener opener = new BrowserWindowOpener( CatUI.class );
opener.setFeatures( "height=300,width=500,resizable" );
opener.extend( this.button );
opener.setParameter( "cat_id" , new UUID(0,0).toString()); // Send nil UUID (all zeros) if nothing selected.
System.out.println( "BWO URL: " + opener.getUrl() );
this.button.setEnabled( false );
this.grid = new Grid<>( Cat.class );
this.grid.setCaption( "Cats" );
List<Cat> cats = new DatabaseService().fetchAllCats() ;
this.grid.setItems( cats );
// Every time the user selects a cat in the Grid, assign that cat’s ID to our `BrowserWindowOpener`. This way our button is always prepared to open a window for the selected cat.
this.grid.addSelectionListener( event -> {
Set< Cat > selectedCats = event.getAllSelectedItems();
this.button.setEnabled( selectedCats.size() > 0 );
if ( selectedCats.size() > 0 ) { // If the user selected an item.
Cat cat = selectedCats.stream().findFirst().get();
opener.setParameter( "cat_id" , cat.getId().toString() ); // A UUID’s canonical presentation is as a 36-character hexadecimal string in five groups with HYPHEN-MINUS as delimiter.
} else {
opener.setParameter( "cat_id" , new UUID(0,0).toString()); // Send nil UUID (all zeros) if nothing selected.
}
System.out.println( "BWO URL: " + opener.getUrl() );
} );
this.grid.select( cats.stream().findFirst().get() ); // Select first item arbitrarily, to provoke the grid’s selection-listener above to fire.
button.addClickListener( e -> {
System.out.println( "BASIL opening now window" );
} );
final VerticalLayout layout = new VerticalLayout();
layout.addComponents( this.grid , button );
setContent( layout );
}
@WebServlet ( urlPatterns = "/*", name = "MyUIServlet", asyncSupported = true )
@VaadinServletConfiguration ( ui = MainUI.class, productionMode = false )
public static class MyUIServlet extends VaadinServlet {
}
}
CatUI
package com.basilbourque.example;
import com.vaadin.server.VaadinRequest;
import com.vaadin.ui.*;
import java.util.Optional;
import java.util.UUID;
public class CatUI extends UI {
private Cat cat = null;
@Override
protected void init ( VaadinRequest vaadinRequest ) {
// Retrieve a parameter from the URI of this UI/window.
String catUuidString = vaadinRequest.getParameter( "cat_id" ); // In the URI key-value parameters, "cat_id" is our key, and a UUID’s hex string is the expected value.
if ( null == catUuidString ) { // If we did not receive the UUID-string parameter we expected.
this.setContent( this.buildLayoutForNoCat( null ) );
return;
}
UUID uuid = UUID.fromString( catUuidString ); // Rehydrate the `UUID` from our passed hex string representing the UUID’s value.
Optional< Cat > cat = new DatabaseService().fetchCat( uuid );
if ( cat.isPresent() ) { // NULL check.
System.out.println( "uuidString: " + uuid + " and cat: " + cat.get() );
this.setContent( this.buildLayoutForCat( cat.get() ) ); // Retrieve the `Cat` object from our `Optional< Cat >` object by calling `get()` only after checking for NULL.
return;
} else { // Failed to find cat.
this.setContent( this.buildLayoutForNoCat( uuid ) );
return;
}
}
private Layout buildLayoutForCat ( Cat cat ) {
this.cat = cat ;
this.getPage().setTitle( "Cat details" );
// Have some content for it
TextField name = new TextField( "Name: " );
name.setWidth( 100 , Unit.PERCENTAGE );
name.setValue( this.cat.getName() );
TextField id = new TextField( "Id: " );
id.setWidth( 100 , Unit.PERCENTAGE );
id.setValue( this.cat.getId().toString() );
VerticalLayout layout = new VerticalLayout();
layout.addComponent( name );
layout.addComponent( id );
return layout;
}
private Layout buildLayoutForNoCat ( UUID uuid ) {
VerticalLayout layout = new VerticalLayout();
String message = "No cat found for the id: " + uuid;
Label label = new Label( message );
layout.addComponentsAndExpand( label );
return layout;
}
}
Cat
package com.basilbourque.example;
import java.util.UUID;
public class Cat {
private UUID id;
private String name;
public Cat ( UUID id , String name ) {
this.id = id;
this.name = name;
}
public UUID getId () {
return id;
}
public void setId ( UUID id ) {
this.id = id;
}
public String getName () {
return name;
}
public void setName ( String name ) {
this.name = name;
}
// Override `Object`.
@Override
public String toString () {
return "Cat{ " +
"id=" + id +
", name='" + name + '\'' +
" }";
}
}
DatabaseService
package com.basilbourque.example;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
// Pretending to be our gateway to a database.
public class DatabaseService {
static private List< Cat > cats;
{
DatabaseService.cats = List.of( // Produces an unmodifiable list. (A new feature in Java 9 and later.)
new Cat( UUID.fromString( "adf5c1a0-912e-11e8-9eb6-529269fb1459" ) , "Fluffy" ) ,
new Cat( UUID.fromString( "d37401c6-912e-11e8-9eb6-529269fb1459" ) , "Spot" ) ,
new Cat( UUID.fromString( "de29b6d8-912e-11e8-9eb6-529269fb1459" ) , "Lilly Mae" )
);
}
public List< Cat > fetchAllCats () {
return new ArrayList<>( DatabaseService.cats ); // Copy the list, then return.
}
public Optional< Cat > fetchCat ( UUID uuid ) {
return DatabaseService.cats.stream().filter( cat -> cat.getId().equals( uuid ) ).findFirst();
}
public static void main ( String[] args ) {
Optional< Cat > cat = new DatabaseService().fetchCat( UUID.fromString( "de29b6d8-912e-11e8-9eb6-529269fb1459" ) );
if ( cat.isPresent() ) {
System.out.println( "cat: " + cat.get() );
} else {
System.out.println( "No cat found." );
}
}
}