1

我一直在尝试在挂毯中创建一个自定义文本字段,当它获得焦点时会呈现一些 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 文件中。如果有人可以帮助或指出正确的方向,我将不胜感激。

4

2 回答 2

4

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

来自Tapestry 5 文档

Tapestry 5 包括一个激进的特性,组件混合。组件混合是一个棘手的概念;它基本上允许将真正的组件与称为 mixins 的特殊受限组件混合在一起。组件及其 mixin 仅表示为组件模板中的单个标记,但包含所有元素的所有行为。

你可以像这样使用 mixin:

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

一个混合存根:

@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。与创建自己的组件相比,mixin 的使用也相对轻量级和优雅。

于 2010-05-10T13:46:22.053 回答
0

.tml

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

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

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

于 2010-05-10T13:11:42.440 回答