猴子补丁:PrimeFaces小部件扩展/覆盖

5

目前我正在使用(它运行良好)

PrimeFaces.widget.OverlayPanel.prototype._old_init = PrimeFaces.widget.OverlayPanel.prototype.init;
PrimeFaces.widget.OverlayPanel.prototype.init = function(cfg) 
{
    this._old_init(cfg);
    this.align();
}

但我希望使用更易读且更加“jQuery”化的代码,例如下面这段完全虚构的代码:

PrimeFaces.widget.OverlayPanel.patch(
{
    init: function(cfg) 
    {
        super.init(cfg);
        this.align();
    },

    show: function()
    {
        console.log('blah blah blah');
        super.show();
    }
});

我尝试使用 PrimeFaces.widget.Xxx.extend({...}),但在这种情况下我无法访问super方法。

请记住,我对Javascript一窍不通

谢谢


你的意思是什么:"所有这种类型的小部件"?是指所有的覆盖面板还是所有其他类型的小部件?如果是前者,只需将其包含在页面模板中即可。 - Kukeltje
你说得对,这是无意义的 - 已从问题中删除。只需在小部件声明后、实例化之前包含脚本即可,使用 *PrimeFaces.cw(...)*。 - Michele Mariotti
好的,明白了。我也曾尝试过使用“extend”,但也没有成功。通常更美观的代码更好,但在这种情况下,我不会花时间去寻找更好的方法,而是使用它已经能够工作的方式(它并不那么丑陋;-) - Kukeltje
这个回答解决了你的问题吗?如何根据widgetVar查找和/或覆盖Primefaces组件中的JavaScript? - Jasper de Vries
当然。但是,我的问题和我的答案自2016年以来就在这里了。你提供的链接的答案是2017年的。所以,我想我会坚持我的已接受的答案。不需要再讨论。 - Michele Mariotti
2个回答

8

我已经实现了它:

if(PrimeFaces.widget.OverlayPanel)
{
    PrimeFaces.widget.OverlayPanel = PrimeFaces.widget.OverlayPanel.extend(
    {
        init: function(cfg) 
        {
            this._super(cfg);
            this.align();
        },

        show: function()
        {
            console.log('blah blah blah');
            this._super();
        }
    });
};

这个被存储在:

  • 应用程序
    • 资源
      • js
        • pf-patches.js

并且它在全局模板中使用:

<!DOCTYPE html>
<html lang="#{userBean.locale.language}" xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:ui="http://xmlns.jcp.org/jsf/facelets" xmlns:h="http://xmlns.jcp.org/jsf/html"
    xmlns:f="http://xmlns.jcp.org/jsf/core" xmlns:cc="http://xmlns.jcp.org/jsf/composite"
    xmlns:c="http://xmlns.jcp.org/jsp/jstl/core" xmlns:fn="http://xmlns.jcp.org/jsp/jstl/functions"
    xmlns:p="http://primefaces.org/ui" xmlns:pe="http://primefaces.org/ui/extensions"
    xmlns:o="http://omnifaces.org/ui" xmlns:of="http://omnifaces.org/functions"
    xmlns:s="http://shapeitalia.com/jsf2" xmlns:sc="http://xmlns.jcp.org/jsf/composite/shape"
    xmlns:e="http://java.sun.com/jsf/composite/cc" xmlns:et="http://shapeitalia.com/edea2"
    xmlns:pt="http://xmlns.jcp.org/jsf/passthrough">

<f:view locale="#{userBean.locale}" contentType="text/html">
    <h:head>
        <f:facet name="first">
            <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1" />
            <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
            <title><ui:insert name="title">#{navigatorBean.viewTitle}</ui:insert></title>
            <link rel="shortcut icon" type="image/x-icon" href="#{resource['favicon/favicon.ico']}" />
        </f:facet>

        <f:facet name="last">
==========> <h:outputScript name="js/pf-patches.js" /> <==========
            <h:outputScript library="omnifaces" name="fixviewstate.js" />
        </f:facet>
    </h:head>

    <h:body>
        <h:outputStylesheet name="theme/custom.css" />
        <h:outputStylesheet name="theme/other-icons.css" />

        ...

1
你把这个放在哪里呢?(顺便说一下,我记得1.5年前的时候this._super(cfg)对我没用...而且我注意到你只在super调用之后添加功能...也许那时候会有用,但我需要改变其中的代码...不过很棒它现在能用了,谢谢你的反馈。) - Kukeltje

2
我遇到了同样的问题,但您的解决方案对我的问题不是100%有效 (详情请参见此处https://github.com/primefaces/primefaces/issues/1928)),因为您愿意从OverlayPanel调用_super(),而我正在尝试避免它 (它会执行一些我不想要的操作)。所以我做的是这样的:
/* Quick fix so layout might be handled in dialog component PF #1928 */
if(PrimeFaces.widget.Layout) {
    PrimeFaces.widget.Layout.prototype.init = function(cfg) {
        // skip calling PrimeFaces.widget.Layout.init() on purpose
        PrimeFaces.widget.DeferredWidget.prototype.init.call(this, cfg);

        this.cfg = cfg;
        this.id = this.cfg.id;
        this.jqId = PrimeFaces.escapeClientId(this.id);

        if(this.cfg.full) {          //full
            var dialog = $(this.cfg.center.paneSelector).parents('.ui-dialog-content');
            if(dialog) {             // full + dialog
                this.jq = dialog;
            } else {
                this.jq = $('body');
            }
        } else if(this.cfg.parent) { //nested
            this.jq = $(PrimeFaces.escapeClientId(this.cfg.parent));
        } else {                     //element
            this.jq = $(this.jqId);
        }

        this.renderDeferred();
    }
}

这样init()就被完全覆盖了。我希望这能帮助一些在这种非典型情况下的人;)


2
正如您在问题中所看到的,目标实际上是要访问super方法。然而,如果在不调用this._super(...)的情况下使用我自己答案中的代码,则会导致完全被覆盖。出于这两个原因,我不认为您的答案有什么附加价值。 - Michele Mariotti
我在寻找解决问题的方法。通过 https://jsf.zeef.com/bauke.scholtz,我阅读了“在JS中扩展/覆盖PrimeFaces.widget”,这正是我想要做的。你的解决方案帮助我入门,我只是发现你的问题并不完全类似于我的。但仍然值得分享解决方案。对于想要“扩展/覆盖PrimeFaces小部件”的人来说,这是一个附加值。如果你认为这没有用,我会简单地删除我的帖子(因为我不是直接回答你的问题,而是为它增加价值,让有需要的人受益)。 - Rapster
2
我仍然认为那正是我试图避免的,但它仍然是“合法”的代码,我不会告诉你删除或保留它,你可以自由地按照自己的意愿去做。尽管如此,除非你编辑你的答案并添加一些我认为有价值的内容,否则我将不会(也不能)取消我的踩。抱歉。 - Michele Mariotti

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接