在动态AJAX加载中,存储支持JSON的最佳位置在哪里?

3
场景:我有一个带有动态模态对话框的HTML页面。页面上的链接打开对话框,但根据点击的链接不同,内容也不同。对话框内容使用AJAX请求加载,并仅包含所需的HTML-例如,没有html或head标签。
在对话框中,有一个“状态”显示和一些日期选择器(例如,“已激活”和“已删除”)。随着日期的更改,状态应更新以根据日期显示当前状态。这很容易做到。
在应用程序中,我有一个用于表示状态的枚举,并且我希望此对话框中的JavaScript使用与服务器端应用程序相同的状态列表。我认为MVC(服务器端)应该生成一些JSON,列出枚举条目,例如:
{ "active": "Active", "removed", "Removed" }

现在的问题是:如果JSON是与模态框内容一起加载的,最好将其放在页面的哪个位置? 以下是我考虑过的一些选项:
  • 我可以将它存储在 head 中的变量中,但我不需要它出现在应用程序的每个页面上。
  • 当模态框加载时,我可以使用被模态框内容调用的 JS 函数将其插入到 head 中或添加到文档元素中。
  • 我可以将其存储在状态显示元素的数据标记中。

如果JSON仅将由模态对话框使用,为什么需要将其放在其他地方,即对话框之外?或者您想通过其他类似的对话框重用它吗? - Greendrake
这就是我所问的 - 假设我不想在需要之前加载它;如果它被应用于第一个模态对话框并被所有其他对话框使用,那很好,但它也可以仅包含在对话框中,并且仅在打开该对话框时使用。那么JSON应该放在哪里? - Eraph
4个回答

1

理想情况下,保存/存储数据的位置应该在视图模型中。然后,您可以使用类似于angularS或knockout.js的东西将必要的DOM元素绑定到它们相关的JSON数据集。如果您需要此类示例,我可以提供一个示例。如果您想采用传统方法,除非这些数据集是动态更改的,否则我建议最好是在服务页面后,在document.ready()后循环每个数据集以保持加载时间。

这有点是一个开放性答案,您将不得不根据您的特定情况/需求选择最佳方案。


谢谢你的回答,但我没有使用客户端MVC。为此加入Angular或Knockout将是完全过度设计! - Eraph
1
我所指的是一个视图模型。你不需要一个复杂的客户端框架来实现这个,你只需要保持模型与用户界面的分离。它可以非常简单,比如使用 $.get('MyViewModel.json', function(jsonData){ $('#myDialog').data = jsonData.whatever }); - voidzero
我现在明白你的意思了,这是与被接受的答案类似的想法。 - Eraph

1
根据您的描述,我会将这个存储在一个与之相关联的元素的数据属性中。
例如:
<div id="myelementid" data-status="@statusserverside" />

你可以在后端使用Razor来填充这个内容,这样它就会出现在与该元素相关的标记/页面中,你可以轻松地从脚本中访问它。
示例:(jQuery,但这只是一个例子)
var initialstatus = {
    "active": "Active",
        "removed": "Removed"
};
// push it in there
$('#myelementid').data("status", initialstatus);
// access it later
var status = $('#myelementid').data("status");
// access one property:
alert($('#myelementid').data("status").active);
// update one property
$('#myelementid').data("status").active = "FRED";
//list the properties(keys)
for (var key in status) {
    if (status.hasOwnProperty(key)) {
        /* useful code here */
        alert(key + ":" + status.active + status[key]);
    }
}

实际示例:在元素中存储ajax的URL。
<div id="myfriend" data-url="@Url.Action("someaction", "somecontroller")" ></div>

现在是有趣的部分:在ajax调用中使用此URL:
var myStoredUrl = $('#myfriend').data("url");
var myajax = $.ajax({
    url: myStoredUrl,
    //...other ajax stuff
});
myajax.done(function (data) {
//done stuff
});

现在,如果您进行重构,就不需要记住站点的URL、根目录等信息来添加到前面,这个过程为您完成。
与您的问题(存储位置)具有相同的净效应,只是一个不同的视角,在我的生产中表现良好。

这是一个好答案!我的倾向是将它存储在将使用它的元素中。我希望你不介意我暂时未将其标记为答案,因为我想看看其他人有什么建议,并找出是否存在这种情况下的最佳实践。 - Eraph

1
如果JSON与模态框内容一起加载,最好将其放在页面的哪个位置?
假设我希望只有在需要时才加载它;如果将其应用于第一个模态对话框并被所有其他对话框使用,那就很好,但它也可以仅包含在对话框中,并且仅在打开该对话框时使用。那么JSON应该放在哪里?
嗯,在网页上保留JSON数据很容易。不需要考虑HTML元素作为数据载体。您只需将其放在全局对象window中。假设您称要保存数据的位置为VAULT:
    // So, we have the JSON come from the sevrer side:
    var options = { "active": "Active", "removed", "Removed" };
    // Now, let's save it on the page:
    window.VAULT = {};
    VAULT.options = options;

或者直接将options放入window中(不建议这样做,因为可能会在全局范围内创建混乱并导致冲突):

    window.modalOptions = options;

然而,如果您每次加载模态框内容时都会使用 AJAX 请求加载您的 JSON,为什么要将其放在对话框之外呢?只需将其保留在对话框内即可:

    // So, we have the JSON come from the server side:
    var options = { "active": "Active", "removed", "Removed" };

    // We have the dialog element (can be obtained in any other way):
    var dialog = document.getElementById('dialogId');

    // Now, just PUT the data in there:
    dialog.data = options;

    // Reuse it later:
    options = dialog.data;

再次强调,在您的情况下不需要使用HTML元素属性来存储数据。这种技术用于从服务器端“传递”数据,但是一旦数据已经可用,使用它只会使事情变得更加复杂。

更新:通过AJAX传递JSON的最佳实践

简短回答:使用JSON来保存所有内容,将数据和HTML标记分离。

详细回答:

响应用于显示模态对话框的AJAX调用的服务器应该返回JSON,其中HTML标记应与任何其他数据分开。例如,返回的JSON可能如下所示:

    {
        "html": "<div>Dialog.. blablabla</div>",
        "data": {
            "options": { "active": "Active", "removed", "Removed" }
        }
    }

您的AJAX回调需要了解响应结构以查找和应用HTML标记。实际代码将根据您使用的JavaScript框架是否/何种而有所不同,但大致如下:
1.需要解析响应JSON(通常使用大多数现代JavaScript工具自动完成):
var response = JSON.parse(responseText);
2.HTML标记可用于应用于模式对话框:
response.html
3.options数据(在您的问题中构成“JSON”)将可用作:
response.data.options

另一个好的答案,我喜欢将JSON存储在将使用它的元素中的想法(就像之前提到的“数据”属性建议)。因此,在这种情况下,可以通过JavaScript设置为元素的“虚构”属性(但不在HTML中显示),但是当模态内容加载时如何调用它?我想在成功加载后可以对模态内容中的任意函数进行调用,但是否有更好的方法? - Eraph
我猜你已经有一个将加载的内容应用于对话框的函数了,是吗?你也会编写一些逻辑代码来使用“选项”数据应用于状态显示吧?所以你只需要修改那些代码片段,让它们使用我在答案中展示的方法即可。 - Greendrake
我理解你的意思,这很好,但是它并没有完全回答JSON应该放在哪里的问题。用于打开和填充模态框的JavaScript函数位于单独的.js文件中。因此,JSON将嵌入在由AJAX调用调用的HTML结果中。这就是我认为“数据属性”答案有意义的地方。 - Eraph
现在我想我误解了你最初的问题。我认为将JSON嵌入由AJAX调用的HTML结果是一件确定的事情——这是你正在做的方式,一切都已经解决了,你很满意。问题是在处理对话框时要保留JSON的位置。现在,如果你问如何通过AJAX调用传递JSON,答案会有所不同。这就是你在问的吗? - Greendrake
抱歉,但是是的,这就是我的问题。在这种情况下,什么被认为是良好的实践呢? - Eraph
这是一个非常好的答案,非常详尽,并且重要的是保持了关注点分离。 - Eraph

0

对于这种特殊情况,另一个解决方案不涉及JSON。我一直认为需要JSON(或类似的东西)才能提供我所需的解决方案,但实际上有一个更简单的解决方案。

状态属性会根据应用于日期字段的设置进行更新。一段JavaScript代码将确定哪个日期字段包含最近的日期,并相应地设置状态。

解决方案:在日期选择器控件中存储状态字符串。

在Razor示例中,可能看起来像这样:

<div class="date-picker" name="ActiveDate" data-status-name="@Enums.Status.Active.Description()" />

感谢所有的答案,能够了解到处理类似情况的可能方法是非常棒的。


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