【问题标题】:How do I create a custom text field in Tapestry5 that renders some Javascript onto the page?如何在 Tapestry5 中创建一个自定义文本字段,将一些 Javascript 呈现到页面上?
【发布时间】:2011-02-17 14:46:31
【问题描述】:

我一直在尝试在 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 文件中。如果有人可以帮助或指出正确的方向,我将不胜感激。

【问题讨论】:

    标签: java javascript custom-component tapestry


    【解决方案1】:

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

    来自Tapestry 5 docs:

    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 也相对轻量级和优雅。

    【讨论】:

    • 感谢您的回答,非常有帮助。但是,我不确定应该将 Mixin.java 类放在哪里?我在某个地方读到我应该把它放在一个名为 mixins 的子文件夹中。我应该创建这个文件夹吗?我尝试创建文件夹并将我的 mixin 类放在那里,但是当我运行应用程序时,我得到一个异常,说找不到 mixin。我正在使用 maven 和 eclipse 来开发我的项目。任何帮助将非常感激。再次感谢。
    • @Shane:是的,'mixins' 是 Tapestry 的神奇包之一,就像 'components' 和 'pages' 一样。如果你把它放在“页面”和“组件”旁边,一切都应该工作。添加包后,您可能必须重新启动应用程序,因为实时重新加载不适用于新创建的包。 (当然,类名必须与您在t:mixins 中指定的类型匹配。)
    • 再次感谢亨宁。最后一个问题,我有一个 javascript 文件,我希望在文本字段获得焦点时运行它。如果这个脚本包含在 mixin.js 文件中,这就是我一直在尝试做的。例如,我的脚本有一个 init() 函数,我希望在 mixin.js 中的 onfcus 事件中调用它我所做的是复制并粘贴您为 mixin.js 提供的代码(调整此代码以满足我的需要) 进入我希望运行的 javascript 文件的顶部。我会以正确的方式解决这个问题吗?对不起,如果这是一个愚蠢的问题。我是这个概念的新手。
    • Prototype 是所有使用 JS 的内置组件的基础,因此在编写 JS 时使用它是有意义的。每当文本字段获得焦点时,我的示例 JS 类应该执行 onFocus() 方法。文本字段为this.textField。您可以将您的脚本集成到 onFocus 方法中,或者只是按照您最初的意图在那里调用您的脚本的 init() 方法。如果您不确定什么是有效的以及为什么,在 Firebug 中设置断点或在调试时将 alert() 语句放在适当的位置会有所帮助。
    • 谢谢,我现在对 javascript mixin 的工作原理有了更清晰的认识。如果我想在 javascript 中获取文本字段的 ID,我会调用 this.textField.getID(); 吗?
    【解决方案2】:

    .tml

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

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

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

    【讨论】:

      猜你喜欢
      • 2023-03-26
      • 2022-07-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-09
      • 1970-01-01
      相关资源
      最近更新 更多