【问题标题】:Setup jQuery listeners off of the global scope在全局范围之外设置 jQuery 侦听器
【发布时间】:2014-12-24 03:43:51
【问题描述】:

自从我对 jQuery(或一般的 javascript)做了很多工作以来,已经有一段时间了。我试图让我们的应用程序从拥有全局范围内的所有方法,到一切都在它自己的命名空间中。

我采用的方法是混合使用显示模块模式和对象字面量模式。

我在每个单独的页面上使用对象文字模式,并且我使用它来简单地设置来自服务器的变量(ASP.NET MVC Razor)

var st = st || {};
st.SharedContextMenuCommon = {
    ContextMenuControllerName: '@Model.ControllerName',
    BindingTargetName: '@Model.TargetName',
    StratosphereGlobalImageUrl: '@Web_Helpers.StratosphereImageUrl("")'  // yes this is empty since we only need the root. we can't pass a JS variable to Razor
};

从这里,我有一个完成所有繁重工作的外部文件。在这种特殊情况下,我有一个 Kendo ContextMenu,我需要它来从嵌套命名空间中初始化它的侦听器 (jQuery)。

如果我删除所有命名空间位,此代码将按预期工作,但是,当我使用显示模块模式时,侦听器不会触发“点击”事件。

var st = st || {};
st.SharedContextMenu = (function() {
    // check to see if menu exists
    var menu = $("#contextMenu");

    var initMenu = function() {
        menu = $("#contextMenu").kendoContextMenu({
            orientation: 'vertical',
            alignToAnchor: true,
            filter: ".contextMenu",
            showOn: "click",
            animation: {
                open: {
                    effects: "fadeIn"
                },
                duration: 250
            },
            select: function(e) {
                this.close(); // close the context menu
                var action = $(e.item).find("[data-action]").data("action"); // extract the javascript string that is to be actioned on
                var id1 = e.target.dataset.recordid; // extract the specific record ID (typically a GUID)
                var id2 = e.target.dataset.recordidalt; // extract the specific alt record ID (typically a GUID)
                var func = new Function(String.format(action, id1, id2)); // format the action (if the string is a formattable)
                return (func()); // execute the string. This is essentially like EVAL, but since this is an internal app, it should be safe.
            }
        });
    };

    // only init the menu if it exists.
    if (menu) {
        initMenu();
        $('#' + st.SharedContextMenuCommon.BindingTargetName).on('click', '.contextMenu', function() {
            var recordId = $(this).data('recordid');
            $.getJSON(st.SharedContextMenuCommon.ContextMenuControllerName + '/?recordId=' + recordId, function(data) {
                var contextMenu = $('#contextMenu').data('kendoContextMenu');
                var items = [];
                $.each(data, function(key, value) {
                    items.push({
                        text: '<span data-action="' + value.OnClickJavascript + '">' + value.Text + '</span>',
                        encoded: false,
                        imageUrl: st.SharedContextMenuCommon.StratosphereGlobalImageUrl + value.Image
                    });
                });

                contextMenu.setOptions({
                    dataSource: items
                });
            });
        });
    }
})();

有人可以指出我缺少的部分吗?

【问题讨论】:

  • 你意识到new function 并没有真正创建一个可以稍后调用的函数,它调用函数构造函数并立即执行新函数。看来您应该删除 new 关键字。
  • @adeneo,对于这种情况,您可能在这两点上都是正确的。在其他领域,使用相同的模式,我返回st,以便可以调用公共方法。在这种情况下,我没有调用任何东西,而只是监听事件。 new function 允许 st.something.publicMethod() 而不是 st.something().publicMethod()... 再次,因为我没有公开公共方法,这没有实际意义,只是一个偏好。

标签: jquery javascript-namespaces revealing-module-pattern


【解决方案1】:

好的,所以我几乎做对了...结果它仍然需要嵌套在文档就绪调用中。

"USE STRICT";

var st = st || {};
$(document).ready(function () {
    setTimeout(function () {
        st.SharedContextMenu = (function () {
            // check to see if menu exists
            var menu = $("#stratosphereContextMenu");

            var onMenuItemSelected = function (e) {
                this.close(); // close the context menu
                var action = $(e.item).find("[data-action]").data("action"); // extract the javascript string that is to be actioned on
                var id1 = e.target.dataset.recordid; // extract the specific record ID (typically a GUID)
                var id2 = e.target.dataset.recordidalt; // extract the specific alt record ID (typically a GUID)
                var func = new Function(String.format(action, id1, id2)); // format the action (if the string is a formattable)
                return (func()); // execute the string. This is essentially like EVAL, but since this is an internal app, it should be safe.
            };

            var initMenu = function () {
                menu = $("#stratosphereContextMenu").kendoContextMenu({
                    orientation: 'vertical',
                    alignToAnchor: true,
                    filter: ".contextMenu",
                    showOn: "click",
                    animation: {
                        open: {
                            effects: "fadeIn"
                        },
                        duration: 250
                    },
                    select: onMenuItemSelected
                });
            };

            // only init the menu if it exists.
            if (menu) {
                initMenu();
                $('#' + st.SharedContextMenuCommon.BindingTargetName).on('click', '.contextMenu', function () {
                    var recordId = $(this).data('recordid');
                    $.getJSON(st.SharedContextMenuCommon.ContextMenuControllerName + '/?recordId=' + recordId, function (data) {
                        var contextMenu = $('#stratosphereContextMenu').data('kendoContextMenu');
                        var items = [];
                        $.each(data, function (key, value) {
                            items.push({
                                text: '<span data-action="' + value.OnClickJavascript + '">' + value.Text + '</span>',
                                encoded: false,
                                imageUrl: st.SharedContextMenuCommon.StratosphereGlobalImageUrl + value.Image
                            });
                        });

                        contextMenu.setOptions({
                            dataSource: items
                        });
                    });
                });
            }
        })();
    }, 0);
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-24
    • 1970-01-01
    • 1970-01-01
    • 2011-08-16
    • 2016-06-14
    • 2010-10-21
    • 1970-01-01
    • 2022-08-16
    相关资源
    最近更新 更多