如何在 Tapestry5 中创建自定义文本字段以将一些 Javascript 呈现到页面上?

发布于 2024-08-31 13:17:03 字数 1110 浏览 4 评论 0原文

我一直在尝试在 Tapestry 中创建一个自定义文本字段,当获得焦点时它将呈现一些 javascript。但我一直很难找到这样的例子。

这是我开始使用的一些代码:

package asc.components;

import org.apache.tapestry5.ComponentResources;
import org.apache.tapestry5.Field;
import org.apache.tapestry5.annotations.Parameter;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.services.ComponentDefaultProvider;


public class DahserTextField implements Field {

@Parameter (defaultPrefix = "literal")
private String label;
@Inject
private ComponentResources resources;
@Inject
private ComponentDefaultProvider defaultProvider;
@Parameter
private boolean disabled;
@Parameter
private boolean required;

String defaultLabel(){
    return defaultProvider.defaultLabel(resources);
}

public String getControlName() {
    return null;
}

public String getLabel() {
    return label;
}

public boolean isDisabled() {
    return disabled;
}

public boolean isRequired() {
    return required;
}

public String getClientId() {
    return resources.getId();
}


}

我不确定下一步要做什么。我不知道要在 .tml 文件中放入什么内容。如果有人能帮助我或为我指出正确的方向,我将不胜感激。

I have been trying to create a custom textfield in tapestry which will render some javascript when it gains focus. But I have been having trouble trying to find an example of this.

Here is some of the code i have started off with:

package asc.components;

import org.apache.tapestry5.ComponentResources;
import org.apache.tapestry5.Field;
import org.apache.tapestry5.annotations.Parameter;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.services.ComponentDefaultProvider;


public class DahserTextField implements Field {

@Parameter (defaultPrefix = "literal")
private String label;
@Inject
private ComponentResources resources;
@Inject
private ComponentDefaultProvider defaultProvider;
@Parameter
private boolean disabled;
@Parameter
private boolean required;

String defaultLabel(){
    return defaultProvider.defaultLabel(resources);
}

public String getControlName() {
    return null;
}

public String getLabel() {
    return label;
}

public boolean isDisabled() {
    return disabled;
}

public boolean isRequired() {
    return required;
}

public String getClientId() {
    return resources.getId();
}


}

I have been unsure on what to do next. I do not know what to put into the .tml file. I would be grateful if anyone could help or point me in the right direction.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

荒人说梦 2024-09-07 13:17:03

无需在您自己的组件中复制 TextField 的任何功能,而是应该创建一个组件 mixin。 Mixin 旨在向现有组件添加行为。

来自 Tapestry 5 文档

Tapestry 5 包含一个激进的功能,
组件混合。组件混入是
一个棘手的概念;它基本上允许
真正要混合在一起的成分
具有特殊的有限组件称为
混合。该组件及其 mixin
仅表示为单个标签
在组件模板中,但所有
所有元素的行为。

您可以像这样使用 mixin:

<input type="text" t:type="TextField" t:mixins="MyMixin" t:someParam="foo" />

一个 mixin 存根:

@IncludeJavaScriptLibrary("MyMixin.js")
public class MyMixin {

    /**
     * Some string param.
     */
    @Parameter(required = true, defaultPrefix = BindingConstants.LITERAL)
    private String someParam;

    @Environmental
    private RenderSupport renderSupport;

    @InjectContainer
    private AbstractTextField field;

    @AfterRender
    void addScript() {
        this.renderSupport.addScript("new MyJavascriptClass('%s', '%s');", 
                this.field.getClientId(), this.someParam);
    }

}

注意 @InjectContainer 注释,它将包含的 TextField 注入到您的 Mixin 中。在本例中,我们需要 TextField 的 clientId。

另请注意 @IncludeJavaScriptLibrary("MyMixin.js") 注释,其中包含所需的 Javascript 文件。

Javascript 可能如下所示:

MyJavascriptClass = Class.create({

    initialize: function(textField, someParam) 
    {
        this.textField = $(textField);
        this.someParam = someParam;

        this.textField.observe('focus', this.onFocus.bindAsEventListener(this));
    },

    onFocus: function(event)
    {
        //do something
    }
}

与您的方法的主要区别在于,这涉及定义您自己的 JS 类并使用 Tapestry 的内置工具来加载和初始化 JS。与创建自己的组件相比,mixins 的使用也相对轻量且优雅。

There is no need to replicate any of TextField's functionality in your own component, instead you should create a component mixin. Mixins are designed to add behaviour to existing components.

From the Tapestry 5 docs:

Tapestry 5 includes a radical feature,
component mixins. Component mixins are
a tricky concept; it basically allows
a true component to be mixed together
with special limited components called
mixins. The component plus its mixins
are represented as just a single tag
in the component template, but all the
behavior of all the elements.

You would use the mixin like this:

<input type="text" t:type="TextField" t:mixins="MyMixin" t:someParam="foo" />

A mixin stub:

@IncludeJavaScriptLibrary("MyMixin.js")
public class MyMixin {

    /**
     * Some string param.
     */
    @Parameter(required = true, defaultPrefix = BindingConstants.LITERAL)
    private String someParam;

    @Environmental
    private RenderSupport renderSupport;

    @InjectContainer
    private AbstractTextField field;

    @AfterRender
    void addScript() {
        this.renderSupport.addScript("new MyJavascriptClass('%s', '%s');", 
                this.field.getClientId(), this.someParam);
    }

}

Note the @InjectContainer annotation, which injects the containing TextField into your Mixin. In this case, we want the TextField's clientId.

Also note the @IncludeJavaScriptLibrary("MyMixin.js") annotation, which includes the required Javascript file.

The Javascript could look like this:

MyJavascriptClass = Class.create({

    initialize: function(textField, someParam) 
    {
        this.textField = $(textField);
        this.someParam = someParam;

        this.textField.observe('focus', this.onFocus.bindAsEventListener(this));
    },

    onFocus: function(event)
    {
        //do something
    }
}

The key difference to your approach is that this involves defining your own JS class and using Tapestry's built-in facilities to load and initialize the JS. The use of mixins is also relatively light-weight and elegant in comparison to creating your own components.

只是我以为 2024-09-07 13:17:03

.tml

<t:textfield onfocus="somethingCool()" />

Java 应该扩展 TextField 吗?它也可能需要导入一个新的样式表。

--
页面实际上是组件,因此您可以像构建任何其他页面一样构建组件。您可以将任何其他组件嵌入其中。我希望这对您来说是一个良好的起点。

The .tml

<t:textfield onfocus="somethingCool()" />

The Java should probably extent TextField? It will need to import a new stylesheet too probably.

--
Pages are actually components, so you would build a component just like you would have any other page. You can embed any other component into them. I hope this is a good starting point for you.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文