【问题标题】:Evolutive string substitution进化字符串替换
【发布时间】:2025-12-21 08:00:11
【问题描述】:

我构建了一个 JQuery 组件来制作下拉手风琴元素。每次我点击手风琴中的一个项目时,它都会保存选择,关闭这个手风琴并打开下一个(如果存在)。

要添加数据,它可以正常工作:

$(window).ready(function () {
    $(selector).data('dropdownaccordion').enqueueAccordion({ // Ajax parameter
            name: "Commune",
            data: {
                url: "/trends/list",
                method: 'GET',
                datatype: "json",
                timeout: 5000
            }
        },
        {
            name: "Batiment",
            data: {
                url: "/trends/list/"+this.path[0], // this.path[0] refer to the first selection, as this.path[1] will refer to the second etc
                method: 'GET',
                datatype: "json",
                timeout: 5000
            }
        },
        { //Note that we can pass array instead of Ajax parameter
            name: "Dummy",
            data: ["One", "Two", "Three"]
        })
});

我设计的组件可以很好地与 Rest API 配合使用。

我添加的第二个元素暴露了问题。如您所见,我正在尝试传递 this.path[0],引用 第一个选择的项目。但是属性路径不存在于 $(windows).ready 范围内,而是存在于 $(selector).data('dropdownaccordion') 范围内。

我可以用$(selector).data('dropdownaccordion').path[0] 替换它,但我想要更全球化的东西,比如 ExpressJS 在 URL 中所做的(http://www.dummy.com/path/:item1/:item2 并由用户选择替换 :itemx)

你知道更好的解决方案吗?如果不知道,你知道如何让它变得更好吗?

编辑

我的组件设计如下:

+function ($) {
    'use strict';
    /**
     * Dropdown_Accordion CLASS DEFINITION
     */
    function DropdownAccordion(component, ...accordions) {
        this.accordions = [];

        for(var i=0;i<accordions.length;i++){
            this.accordions.push(accordions[i])
        }

        ...
        this.component = $(component);

        ...
        // Render the accordions as DOM
        this.render.call(this);

        //Events
        this.component
            .on("click", ".accordion-item-body", $.proxy(function(event){
                this.path.push($(event.target).text())
                this.component.trigger('click.selection.dropdownaccordion', [$(event.target)])
                this.openNext(event);
            }, this))
            .on('show.bs.dropdown', $.proxy(this.showMenu, this))
            .on('shown.bs.dropdown', $.proxy(this.openNext, this))
            .on('hide.bs.dropdown', $.proxy(function (event) {
                this.component.find('.dropdown-menu').first().stop(true, true).slideUp();
                this.component.find(".accordion-item .panel-collapse.collapse").each(function(){
                    $(this).collapse('hide');
                });
                this.opened = null;
                (this.path.length !== this.accordions.length) ? this.component.trigger("abort.selection.dropdownaccordion", [this.path]):null
                this.path = []
            }, this));
    }

    DropdownAccordion.prototype = {
        constructor: DropdownAccordion,
        // Collapse accordion every time dropdown is shown
        showMenu: function () {
            // show the accordion
        },

        openNext: function (clickEvent) {
           // Open the next accordion
        },

        render: function () {
            // Will render the dropdown-accordion
            // The following is how the AJAX request is performed
            ...
            // When the accordion is opened, make the ajax request
            DOMaccordion.on("open.accordion.dropdownaccordion", function () {
                    // The DOM element contains in data the options for the ajax request, or nothing if the accordion is an array    
                    **$.ajax($(this).data('content.accordion.dropdownaccordion'))** 

            });
            ...
            }
        },
        enqueueAccordion: function (...accordions) {
            for(var i=0; i<accordions.length;i++)
                this.accordions.push(accordions[i]);
            this.render()
        },

        dequeueAccordion: function (name) {
            this.accordions = this.accordions.filter(function (obj) {
                return obj.name !== name;
            })
            this.render()
        }
    }

查看代码中的** **,这里是Ajax 选项的存放位置。我希望当我单击一个项目时,.url 上有一个替换项以包含单击的第一个项目。

我希望这对你来说更清楚。

【问题讨论】:

  • 不清楚您到底要/想要达到什么目标?显示您认为可行的代码,而不是显示随机代码
  • 我编辑了这篇文章。希望越来越好

标签: javascript jquery substitution


【解决方案1】:

您可以让enqueueAccordion 接受回调并将当前手风琴作为参数传递:

DropdownAccordion.prototype = {
    // ...
    enqueueAccordion: function (makeAccordions) {
        var accordions = makeAccordions(this);

        for (var i = 0; i < accordions.length; i++)
            this.accordions.push(accordions[i]);
        this.render();
    }
}

$(selector).data('dropdownaccordion').enqueueAccordion(function (_this) {
    return [
        {
            name: "Batiment",
            data: {
                url: "/trends/list/" + _this.path[0],
                method: 'GET',
                datatype: "json",
                timeout: 5000
        }
    ];
});

如果要直接使用this,可以暂时将回调附加到当前手风琴:

DropdownAccordion.prototype = {
    // ...
    enqueueAccordion: function (makeAccordions) {
        this.makeAccordions = makeAccordions;
        var accordions = this.makeAccordions();
        delete this.makeAccordions;

        for (var i = 0; i < accordions.length; i++)
            this.accordions.push(accordions[i]);
        this.render();
    }
}

$(selector).data('dropdownaccordion').enqueueAccordion(function () {
    return [ // Ajax parameters
        {
            name: "Batiment",
            data: {
                url: "/trends/list/" + this.path[0],
                method: 'GET',
                datatype: "json",
                timeout: 5000
            }
        }
    ];
});

【讨论】:

    【解决方案2】:

    我挖掘了 expressjs 代码,发现了他们是如何进行 URL 替换的。它与 path-to-regex 模块一起使用。它似乎不是为浏览器端开发的,所以我不得不找到另一个解决方案。

    @aaron 启发了我,我终于添加了使用回调代替 url 的可能性:

    {
                name: "Capteur",
                data: {
                    url: function (path) {
                        return "/trends/list/" + path[0] + "/" + path[1]
                    },
                    method: 'GET',
                    datatype: "json",
                    timeout: 5000
                }
            }
    

    通过这样做,人们现在可以根据之前的选择修改路径。

    【讨论】: