1

根据下面的代码,我有一个变量,一旦加载页面mdcDialog,它就会使用 (MDCDialog) 库进行初始化。material-components-web

在提交表单时,会阻止默认事件,而是ajaxSubmit()处理表单。
响应是一个 json 对象,我可以从中找到response.modal.modal带有字符串 value的变量mdcDialog

但是出于某种原因,console.info(window[response.modal.modal]);返回 undefined 而不是 variable mdcDialog
另一方面,console.log(mdcDialog)按应有的方式输出变量。

如果不起作用,我如何mdcDialog从字符串响应中访问我的变量?window

app.js

/* --- VARS --- */
const page="#page";
let mdcDialog;

/* --- FUNCTIONS --- */
function ajaxSubmit(node) {
    $.ajax({
        type: node.attr("method"),
        url: node.attr("action"),
        enctype: "multipart/form-data",
        data: new FormData(node[0]),
        processData: false,
        contentType: false,
        cache: false
    }).done(function(response, status, xhr) {
        if(response !== false) {
            /** @var response.modal */
            if(typeof response.modal !== "undefined") {
                /** @var response.modal.action */
                /** @var response.modal.modal */
                /** @var response.modal.content */
                if(response.modal.action === "load") {
                    console.info(window[response.modal.modal]);
                }
            }
        }

    }).fail(function(request, status, error) {
        console.error(request);
        console.error(status);
        console.error(error);
    });
}

/* --- ACTIONS --- */
$(document).ready(function() {
    mdcDialog=new mdc.dialog.MDCDialog(document.querySelector("#dialog-level.mdc-dialog"));

    $(page).on("submit", ".ajs", function(e) {
        e.preventDefault();
        ajaxSubmit($(this));
    })
});
4

3 回答 3

2

您仅mdcDialog在此函数的范围内定义(如果 javascript 以“严格模式”运行):

$(document).ready(function() {
    mdcDialog=new mdc.dialog.MDCDialog(document.querySelector("#dialog-level.mdc-dialog"));

    ...
});

要赋予它全局范围并使其可通过window['mdcDialog']执行以下操作:

$(document).ready(function() {
    window.mdcDialog = new mdc.dialog.MDCDialog(document.querySelector("#dialog-level.mdc-dialog"));

    ...
});

或者在函数之前的全局范围内定义它:

var mdcDialog;
$(document).ready(function() {
    mdcDialog = new mdc.dialog.MDCDialog(document.querySelector("#dialog-level.mdc-dialog"));

    ...
});

https://www.w3schools.com/js/js_scope.asp

于 2019-08-09T20:07:39.123 回答
1

您的 app.js 文件被视为一个 JavaScript 模块,这意味着您在其中声明的变量默认情况下仅限于该模块而不是添加到该模块中window(这通常是一件坏事)。

如果你想在你的模块之外提供一些东西(在另一个文件中或从你的 HTML 页面/webtools 中),你可以设置global.mdcDialog.

话虽如此,我不确定您在示例中要做什么...如果您需要访问回调中mdc.dialog.MDCDialogcreated的实例$(document).ready,为什么不直接使用mdcDialog

如果您的用例是“我将有多个对话框并且需要检索正确的对话框”,那么将所有实例存储在一个对象中可能是一种更好的方法:

const dialogs = {};

function ajaxSubmit(node) {
    $.ajax({
        // ...
    }).done(function(response, status, xhr) {
        // ...
        console.info(dialogs[response.modal.modal]);
    });
}

$(document).ready(function() {
    dialogs['mdcDialog'] = new mdc.dialog.MDCDialog(/* ... */);

    $(page).on("submit", ".ajs", function(e) {
        e.preventDefault();
        ajaxSubmit($(this));
    })
});
于 2019-08-12T19:55:19.233 回答
1

let使用或具有块范围定义的变量const,即使它们定义在最外层范围内,它们也不会被全局定义,因此永远无法通过全局 ( window) 对象访问。

要以这种方式访问​​它们,您必须使用var, 或在全局对象本身上定义它们。

let foo=1
window.foo //undefined
foo        //1

var bar=2
window.bar //2
bar        //2

window.baz=3
window.baz //3
baz        //3

有关更多信息,请参阅此 SO 答案

于 2019-08-12T20:51:42.843 回答