vaadin_有关自定义Vaadin HTML模板的反馈

vaadin

上周,我的帖子是关于如何自定义默认Vaadin HTML模板,以便可以添加lang属性的。 我没有要求反馈,但是无论如何我都得到了反馈,所以让我们借此机会来分析它。

首先,我必须承认我的解决方案不是Vaadin风格的,因为我使用AOP来完成工作。 我来自Vaadin团队的朋友Matti Tahvonen非常友善,不仅为我的提案提供了一个方案,而且提供了2个方案。 谢谢马蒂!

替代解决方案

第一个解决方案-也是我得到的最后一个解决方案,由AMahdy AbdElAziz提交:

JavaScript.eval("document.querySelector('html').setAttribute('lang', 'fr')")

邪恶,但是有效,再简单不过了!

第二种解决方案使用Matti自己的框架-Viritin来实现。 我还没有看过该框架(但它在我的待办事项列表中),因此我无法对其进行评论,但这是代码段:

@Theme("mytheme")
publicclassMyUIextendsUI{

    @Override
    protectedvoidinit(VaadinRequestvaadinRequest){
        // HtmlElementPropertySetter is part of Viritin add-on https://vaadin.com/directory=!addon/viritin
        HtmlElementPropertySetterheps=newHtmlElementPropertySetter(this);
        heps.setProperty("//html","lang","fr");
        setContent(newLabel("Hello lang attr"));
    }

    @WebServlet(urlPatterns="/*",name="MyUIServlet",asyncSupported=true)
    @VaadinServletConfiguration(ui=MyUI.class,productionMode=false)
    publicstaticclassMyUIServletextendsVaadinServlet{}
}

Vaadin风格的标准服务器端方式有些复杂:

@Theme("mytheme")
publicclassMyUIextendsUI{

    @Override
    protectedvoidinit(VaadinRequestvaadinRequest){
        setContent(newLabel("Hello lang attr"));
    }

    @WebServlet(urlPatterns="/*",name="MyUIServlet",asyncSupported=true)
    @VaadinServletConfiguration(ui=MyUI.class,productionMode=false)
    publicstaticclassMyUIServletextendsVaadinServlet{
        @Override
        protectedvoidservletInitialized()throwsServletException{
            super.servletInitialized();
            getService().addSessionInitListener(e->
                e.getSession().addBootstrapListener(newBootstrapListener(){
                    @Override
                    publicvoidmodifyBootstrapFragment(
                            BootstrapFragmentResponseresponse){
                        // NOP, this is for portlets etc
                    }
                    @Override
                    publicvoidmodifyBootstrapPage(BootstrapPageResponseresponse){
                        response.getDocument().child(0).attr("lang","fr");
                    }
                })
            );
        }
    }
}

但是,我可以对此进行分析和评论:-)

流动分解

注意:对可能的改进更感兴趣的读者可以直接跳到该部分。

第一部分很容易。 它只是注册一个新的SessionInitListener(建议的代码使用lambda做到这一点):

添加会话初始化监听器

第二部分发生在发出请求并且Vaadin注意到必须创建一个新会话时:

处理请求

上一序列图的结尾是在Vaadin中以通用方式设计的。 在我们的特定情况下,它呈现为:

添加Bootstrap侦听器

改进措施

我认为可以进行一些改进。

  • 该代码非常冗长-即使使用Java 8的lambda
  • 每次初始化会话时,都会创建两个对象:会话侦听器和引导侦听器
  • 将servlet类设置为UI的内部类会令我不寒而栗。 尽管我知道这是一个要点,但不幸的是,这是使用Vaadin Maven原型获得的。 这与“单一责任原则”相去甚远。

由于我的最初示例同时使用了Spring Boot和Kotlin,因此这是我的版本:

@Configuration
openclassAppConfiguration{

    // ... Abridged for readability's sake

    @Bean
    openfunvaadinServlet()=CustomVaadinServlet{event:SessionInitEvent->
        event.session.addBootstrapListener(object: BootstrapListener{
            overridefunmodifyBootstrapFragment(response:BootstrapFragmentResponse){
                // NOP, this is for portlets etc
            }
            overridefunmodifyBootstrapPage(response:BootstrapPageResponse){
                response.document.child(0).attr("lang","fr")
            }
        })
    }
}

classCustomVaadinServlet(privatevallistener:(SessionInitEvent)->Unit):SpringVaadinServlet(){
    overridefunservletInitialized(){
        super.servletInitialized();
        service.addSessionInitListener(listener)
    }
}

使用Spring Boot,我可以将SessionInitListener作为一个单例作用域Bean进行管理。 通过将其作为servlet参数传递,我只能分别创建SessionInitListenerBootstrapListener的单个实例。 当然,这是唯一可行的,因为语言值是固定的。

感谢Kotlin,我将重写的Servlet类共放置在配置文件中, 在配置类之外。 由于Servlet仅由配置使用,因此将它们组合在一起是有意义的...但是不要太多。

最后,请注意SessionInitListener是一个功能接口,这意味着它只有一个方法。 此单一方法等效于采用SessionInitEvent并且不返回任何内容的函数。 在Kotlin中,签名是(SessionInitEvent) → Unit 。 我更喜欢使用该函数,而不是创建一个匿名内部类。 这不是改进,而是功能更强大的替代方案。 在运行时,这两种选择都将分配相同数量的内存。

完整的源代码可以在Github上的manage-lang分支中找到。

翻译自: https://blog.frankel.ch/feedback-customizing-vaadin-html-template/

vaadin

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值