【问题标题】:Where is the best place to store supporting JSON on dynamic AJAX load?在动态 AJAX 负载上存储支持 JSON 的最佳位置在哪里?
【发布时间】:2015-11-07 03:52:00
【问题描述】:

场景:我有一个带有动态模式对话框的 HTML 页面。页面上的链接会打开对话框,但会根据点击的链接显示不同的内容。对话框内容是使用 AJAX 请求加载的,并且仅包含所需的 HTML - 例如,没有 html 或 head 标签。

在对话框中,有一个“状态”显示和几个日期选择器(例如“已激活”和“已删除”)。随着日期的变化,状态应该更新以根据日期显示当前状态。我能做到,不用担心。

在应用程序中,我有一个状态枚举,并且我希望此对话框中的 JavaScript 使用与服务器端应用程序相同的状态列表。我认为 MVC(服务器端)应该生成一些 JSON,列出枚举条目,例如:

{ "active": "Active", "removed", "Removed" }

现在的问题!如果加载了模态内容,那么将这个 JSON 放在页面中的最佳位置在哪里? 以下是我考虑过的一些选项:

  • 我可以将它存储在头部的 var 中,但我不需要它出现在应用程序的每个页面中。
  • 当模态加载时,我可以使用模态内容调用的 JS 函数将其插入头部,或将其添加到文档元素。
  • 我可以将它存储在状态显示元素的数据标签中。

【问题讨论】:

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

标签: javascript html json model-view-controller


【解决方案1】:

如果加载了这个 JSON,那么在页面中放置这个 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 中),但是当模态内容加载时如何调用它呢?我想在成功加载时可以调用模态内容中的任意函数,有没有更好的方法?
  • 我猜你已经有一个函数可以将加载的内容应用到对话框,不是吗?您还会有一些逻辑编码,将使用options 数据应用于状态显示?因此,您只需修改这些代码,以便它们使用我在答案中显示的方法。
  • 我知道你来自哪里,这很好,但它并不能完全回答 JSON 的位置。用于打开和填充模式的 JavaScript 函数位于单独的 .js 文件中。因此 JSON 必须嵌入到由 AJAX 调用调用的 HTML 结果中。这就是我认为“数据属性”答案有意义的地方。
  • 现在我想我误解了你原来的问题。我认为将 JSON 嵌入到由 AJAX 调用调用的 HTML 结果中是一件既定的事情——这就是你这样做的方式,一切都解决了,你对此很满意。问题是在处理对话框时将 JSON 保留在哪里。现在,如果您询问如何通过 AJAX 调用传递 JSON,答案会有所不同。你问的是这个吗?
  • 抱歉,但是,这就是我要问的。在这种情况下,什么是好的做法?
【解决方案2】:

根据您的描述,我会将其存储在与之关联的元素的数据属性中。

例子:

<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、根目录等,这可以帮到您。

与您的问题(在哪里存储东西)相同的净效果,只是不同的视角在生产中对我来说效果很好。

【讨论】:

  • 这是一个很好的答案!我倾向于将它存储在将要使用它的元素中。我希望你不介意我还没有将其标记为答案,因为我想看看人们有什么其他建议,并找出这种事情是否有一种最佳实践。
【解决方案3】:

理想情况下,“保存/存储”数据的位置应位于视图模型中。然后,您将使用 angularS 或 knockout.js 之类的东西将必要的 DOM 元素绑定到它们的相关 json 数据集。如果你想要一个这样的例子,我可以旋转一个。如果您想走传统路线,除非这些数据集是动态变化的,否则最好的选择是提供页面,然后在 document.ready() 之后循环每个数据集以缩短加载时间。

这是一个开放的答案,您必须选择最适合您给定场景/需求的答案。

【讨论】:

  • 为答案干杯,但我没有使用客户端 MVC。为此使用 Angular 或 Knockout 完全是矫枉过正!
  • 我的意思是视图模型。您不需要复杂的客户端框架,您只想保持模型与 UI 的分离。它可以像做 $.get('MyViewModel.json', function(jsonData){ $('#myDialog').data = jsonData.whatever }); 一样简单
  • 我现在明白你的意思了,这与接受的答案类似。
【解决方案4】:

针对这种特殊情况的另一种解决方案根本不涉及 JSON。我似乎已经意识到 JSON(或类似的东西)对于提供我需要的解决方案是必要的,而有一个更简单的解决方案。

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

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

在 Razor 示例中,它可能如下所示:

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

感谢所有答案,很高兴能够深入了解处理这种情况的可能方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-25
    • 1970-01-01
    • 2011-01-14
    • 1970-01-01
    相关资源
    最近更新 更多