【问题标题】:Pass function via Custom Control Properties or custom events for Custom Controls?通过自定义控件属性或自定义控件的自定义事件传递函数?
【发布时间】:2012-08-22 12:30:38
【问题描述】:

这就是我想要做的。我有一个带有按钮的自定义控件。如果我将它放在页面上,我希望最终用户程序员定义按下按钮时会发生什么。

我对如何实现这一点有三个想法,但不知道它们是否可能当然不知道如何去做。

  1. 通过自定义属性传递函数。该按钮会将该自定义属性作为函数调用。这可能吗?如果是这样,我会怎么做?我试过了,但似乎没有用。

    compositeData.ssjs_clickOK("Hello World");

  2. 为自定义控件定义自定义事件。这可能吗?怎么做。

  3. 让按钮调用需要由用户程序员定义的唯一函数名称。看起来有点乱,但它可能会起作用。我的按钮代码如何查看功能是否已定义? if (MySpecialFunction != null) 会起作用吗?

【问题讨论】:

    标签: xpages


    【解决方案1】:

    我在我的一个应用程序中使用以下内容将函数传递给自定义控件:

    1) 在自定义控件中,添加一个属性,该属性将保存要在我们的操作按钮中执行的功能。我会打电话给我的'querySave'。属性类型必须是“javax.faces.el.MethodBinding”。编辑器必须是“方法绑定编辑器”。

    2)。以下是此示例的自定义控件中操作按钮背后的代码:

    if (compositeData.querySave) if (!compositeData.querySave.call()) return;
    currentDocument.save();
    

    这表示:如果在属性“querySave”中定义了一个函数,请调用它。如果函数返回 false,则不要保存文档。

    3) 定义一个 SSJS 函数来执行您需要操作按钮执行的操作。我通常把我的放在一个 SSJS 库中。确保 XPage 可以访问该函数。

    4) 在包含此控件的 XPage 中,使用我们在步骤 1 中创建的属性的编辑器(本示例中为 querySave)并输入您在步骤 3 中创建的函数的名称。重要提示:执行输入函数名称时不要添加括号或参数 - 如果这样做,函数将在加载时执行,而不是在您单击操作按钮时执行。另外,不要将任何代码直接添加到编辑器中,只需添加函数名称即可。此编辑器中的任何代码也将在加载时执行。

    感谢Bill Hanson for the answer on Experts Exchange

    --

    更新:

    这是一个具有自定义属性的自定义控件的具体示例,其中相关的 SSJS 函数称为 validateDocument:

    <xc:component_buttons>
        <xc:this.validateFunctionName><![CDATA[#{javascript:validateDocument}]]></xc:this.validateFunctionName>
    </xc:component_buttons>
    

    下面是自定义控件中调用该函数的按钮示例:

    <xp:button id="submit" value="Save">
        <xp:eventHandler event="onclick" submit="true" refreshMode="complete">
            <xp:this.action>
                <xp:actionGroup>
                    <xp:this.condition><![CDATA[#{javascript:
                    if (compositeData.validateFunctionName) {
                        compositeData.validateFunctionName.call();
                    }}]]>
                    </xp:this.condition>
                    <xp:save></xp:save>
                </xp:actionGroup>
            </xp:this.action>
        </xp:eventHandler>
    </xp:button>
    

    【讨论】:

    • 这是有效的。有点。我想我可能对你的最后一步感到困惑。我所做的是创建一个函数并将其放置在 SSJS 库中,我将该库作为资源包含在 xpage 上。然后我只是将函数的名称放在我的 CC 属性中,但出现以下错误 Script interpreter error, line=4, col=36: Java method 'setValue(undefined)' on java class 'com.ibm.xsp.component .xp.XspInputText' 未找到。 setValue 是我的函数的名称。我将 setValue 放在编辑器中,仅此而已。
    • 如果我不传递参数,这很好用。但我希望我的按钮能够将值传递给函数。我猜有点像回调。
    • 布鲁斯,我已经用具体例子更新了我的答案。希望对你有帮助
    • 好问题,布鲁斯。我不知道,因为我没有尝试过。您可以将参数作为其他自定义属性传递。那么问题来了,在使用 .call() 调用函数时如何将参数传递给函数。
    • 我在下面使用了 Sven 的部分解决方案来传递参数。我通过数组传递参数。但我认为你的想法也会奏效,我可能会使用它。看起来更直接。
    【解决方案2】:

    看看这个问题:Pass javascript code to Custom Control

    我的回答描述了如何通过方法绑定从自定义控件传递 SSJS 代码。

    编辑:

    1. 创建自定义控件“ccSSJS”
    2. 将属性 ssjsCode 添加到您的 CC
      • 类型:javax.faces.el.MethodBinding
      • 编辑器:方法绑定编辑器
    3. 这是抄送的来源

      <?xml version="1.0" encoding="UTF-8"?>
      <xp:view xmlns:xp="http://www.ibm.com/xsp/core">
      
         <xp:button value="Label" id="button1">
           <xp:eventHandler event="onclick" submit="true"
              refreshMode="complete">
              <xp:this.action>
                 <![CDATA[#{javascript:
                    var args = new Array();
                    args["abc"] = "123";
                    args["cde"] = "456";
                    compositeData.ssjsCode.invoke( facesContext, null );
                 }]]>
              </xp:this.action>
           </xp:eventHandler>
         </xp:button>
      </xp:view>
      
    4. 创建一个 XPage 并添加自定义控件

      <?xml version="1.0" encoding="UTF-8"?>
      <xp:view xmlns:xp="http://www.ibm.com/xsp/core" xmlns:xc="http://www.ibm.com/xsp/custom">
      
      <xc:ccSSJS>
            <xc:this.ssjsCode>
               <![CDATA[#{javascript:
                  var app = facesContext.getApplication();
                  app.createMethodBinding("#{javascript:print( args['abc'] )}", null); 
               }]]>
            </xc:this.ssjsCode>
         </xc:ccSSJS>
      
      </xp:view>
      

    如果单击自定义控件中的按钮,将调用方法ssjsCode

    【讨论】:

    • 我对 块感到困惑。它去哪儿了?在我的 CC 或 XP 上?
    • 看起来也适用于 CSJS。有没有办法用 SSJS 做到这一点?
    • 块在您的 XPage 上。 ccMethod 是本例中的自定义控件。它适用于 SSJS 和 CSJS。
    • 抱歉这么密集,我是新手。但是有2个CC吗? ccMethod 和 cCSJS?你有一个工作的例子吗?另外如何将对象传递给我的自定义函数?我知道我可以使用其他 CC 属性来做到这一点,但我宁愿通过对象将值传递回我的程序员
    • 在我的回答中添加了一个例子。
    【解决方案3】:

    在包含自定义控件的页面上的任意位置定义一个任意事件处理程序,并确保给它一个 id:

    <xp:eventHandler id="customEvent" event="customEvent">
    <xp:this.action>
    <![CDATA[#{javascript://your custom code}]]>
    </xp:this.action>
    </xp:eventHandler>
    

    然后,您可以将与该事件处理程序关联的方法绑定传递到接受 MethodBinding(或“对象”)的自定义控件的自定义属性中:

    getComponent("customEvent").getAction();
    

    然后,在您的自定义控件内部,您可以直接调用方法绑定:

    var customMethod = compositeData.get("customEvent");
    var customArguments = compositeData.get("customEventArguments");
    customMethod.invoke(facesContext, customArguments);
    

    确保您的自定义控件的“customEventArguments”属性设置为允许多个...这会强制将该属性视为一个数组,这是调用方法所期望的。

    【讨论】:

      【解决方案4】:

      这是第四个选项。不要在自定义控件上包含按钮。相反,使用id="actionButton" 添加一个可编辑区域。您可以通过在自定义控件的设计定义中使用类似这样的内容来告诉开发人员他们需要添加按钮以及添加按钮的位置:

      <?xml version="1.0" encoding="UTF-8"?>
      <xp:view xmlns:xp="http://www.ibm.com/xsp/core" style="background-color:#4a4a4a;color:#fff;">
      Add a button to the facet below.<br/>
      <xp:callback facetName="actionButton" id="callback1"></xp:callback>
      </xp:view>
      

      在设计定义中包含 xp:callback 将在运行时为开发人员提供一个放置区域以添加按钮。 (该按钮可能需要在面板或其他容器控件中,我不确定)。如果您的客户控件上已有其他可编辑区域,您还需要将这些区域包括在设计定义中。

      【讨论】:

        猜你喜欢
        • 2014-11-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-09-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多