为什么在视图中使用AJAX加载内联JavaScript是不好的?

11
我们有一个选项卡界面,在其中一个选项卡中有一个隐私表单。这个隐私表单不仅使用外部JavaScript文件来完成大部分工作,还使用内联JavaScript,因为它目前依赖于动态代码(在服务器端语言中)。
...
<script type ="text/javascript">
    var messagingTabset = ProjectName.Tabset.init({
        'tabID': 'preferences-tabset',
        'ajaxUrl0': '<%=Url.Action("PreferencesMainForm", "Profile")%>',
        'ajaxUrl1': '<%=Url.Action("ProfileImageForm", "Profile")%>',
        'ajaxUrl2': '<%=Url.Action("InterestsForm", "Profile")%>',
        'ajaxUrl3': '<%=Url.Action("PrivacyForm", "Profile")%>',
        'ajaxUrl4': '<%=Url.Action("PasswordForm", "Profile")%>',
        'ajaxUrl5': '<%=Url.Action("CustomUrlForm", "Profile", new {userId = Model.UserId})%>',
        'defaultAjaxUrl': '<%=Url.Action(Model.PartialName, "Profile")%>'
    });
</script>
...

privacyForm view(更多内联Javascript和服务器端代码)

...
<script type = "text/javascript">
    var preferencesPrivacyForm = new ProjectName.AJAX.Form({
        "ajaxFormID": "preferences-privacy-form",
        "actionUrl": '<%= Url.Action("SavePrivacy","Profile") %>',
        "dataReturnType":"json"
    });
</script>
...

后端开发人员: "这个表单的配置JavaScript代码应该留在privacyForm视图中。"

前端开发人员: “嗯,我确定我读过这不是做法-不可靠,所有的JavaScript应该放在包含选项卡包装器的HTML页面内,在该选项卡加载的回调函数内。你应该真正提供逻辑让我获取选项卡包装器内的动态数据或者让我通过DOM遍历获取那些动态变量。”

后端开发人员: "这两种方法都需要很多工作,但没有真正的回报!第一个例子很糟糕,因为这意味着我将不得不改变它的构建方式(并且已经很好地工作)。这可能意味着重复。第二个例子是靠不住的,因为标记可能会改变,所以正在处理代码的人可能会忘记编辑tabs-wrapper中的DOM遍历方法。这是我们不需要的另一个抽象级别。如果您能提供一些关于为什么这真的非常糟糕的证据,那么我会查看它,但是否则我无法证明花费时间的价值。

前端开发人员:“好吧,我已经浪费了几天的时间,通过将它们放在回调函数中修复了与AJAX加载的JavaScript相关的问题,但是是的,现在你想到了这一点,这种事情的好参考将非常好,因为你说得对,目前应用程序正在没有任何问题的情况下运行。”

这是一个大型应用程序中的许多示例之一,我们正在使用Ajax加载内联JavaScript。

我应该说服后端开发人员我们应该使用回调函数,还是我错过了什么?

4个回答

5
我建议阅读戴尔·卡内基的《人性的弱点》。
似乎开发人员经常会陷入这种情况,他们知道什么是最好的做法,但却得不到其他开发人员或管理层的支持。
这本书绝对值得一读;对于这个行业来说,是必读之作。

这是一个非常出乎意料的答案,我认为这很棒。我会查看这本书的。希望你不介意我将问题标题简化为更加技术性的焦点。+1 - Dr. Frankenstein

5

只要它能够起到作用(例如,加载来自其他网站(如WordPress仪表板)的内容),它并不真正“糟糕”,但是除非您绝对需要这样做,否则进行所有额外的服务器调用会浪费资源。

通常,最简单的答案最正确。在这种情况下,意味着不添加所有额外开销以避免稍微重新编码后端。


1

这是关于为什么非侵入式Javascript(UJS)好的核心论点。我以前不理解它的优点,因为我不知道如何在没有内联Javascript的情况下解决问题。最终我学会了。

首先,UJS之所以好,是因为它将您的前端代码分离如下:

  1. HTML - 纯HTML用于构建信息结构。
  2. CSS - CSS用于样式和布局。
  3. Javascript - Javascript用于定义页面行为。

为了使它们协同工作,HTML文件加载外部CSS文件来定义样式和外部Javascript文件来定义行为。此外,您需要在HTML(例如id、类名和标记)、CSS(id和类规则)中使用众所周知的符号,以便您的Javascript可以根据实现的行为来操作结构、布局和样式。

使用jQuery等Javascript框架,您可以动态地将Javascript处理程序绑定到各种HTML DOM对象上的事件上。这使您避免在HTML内联进行操作。

我曾经使用过结构清晰、样式布局良好、行为规范的代码,也曾经使用过HTML、CSS和Javascript混杂在一起的代码,包括使用ERB动态生成的HTML/JS代码。两者都因不同的原因难以理解。第一个难点在于我必须理解每个文件中的内容,而混合代码难以理解是因为我必须弄清楚哪些是JS、哪些是HTML、哪些是CSS、什么时候初始化以及什么是生成的。然而,一旦我掌握了学习曲线,演化结构清晰的代码就变得更加容易测试。

对于生成的Javascript(例如使用ERB),您通常可以将代码结构化,其中静态javascript由某些用户特定或上下文特定数据驱动。如之前的人所建议的那样,您可以在HEAD部分设置该数据的值,然后使用静态Javascript文件。您还可以使用AJAX调用从服务器获取相同的数据。

从短期业务角度来看,后端开发人员是正确的。如果它能够正常工作,就不要修复它。从中期的角度来看,如果您不使用UJS清晰地分离HTML、CSS和Javascript,那么将会花费更多的时间来演变和维护您的代码。从您的业务角度来看,保持现有代码的维护和演变将会很痛苦。从后端开发人员的业务角度来看,如果他做了除了今天有效的事情之外的任何事情,都将会花费更多的成本。也就是说,您的团队领导和架构师需要平衡各种业务观点,以确定如何构建您的代码。


谢谢您提供这个信息,尽管我不确定它与我理解的"不显眼JavaScript"有什么具体关系 - http://icant.co.uk/articles/seven-rules-of-unobtrusive-javascript/。这个问题更关注JavaScript中回调函数的重要性,如果我的措辞不太准确,请见谅。 - Dr. Frankenstein

0

从示例中并不清楚为什么你需要首先使用AJAX。为什么不直接放置

<script type ="text/javascript">
    var userId = "<<<<= userId >>>>"
</script>

直接放在HTML头中?对用户更快,对服务器更简单,还可以避免处理失败请求的时间和错误问题。


我已经更新了代码,展示了更多真实的例子,谢谢。 - Dr. Frankenstein
谢谢,但这并没有更清楚地解释为什么需要 AJAX 调用。将动态数据传递给 JavaScript 的标准方式是在头部设置一个 JavaScript 变量,然后您可以在任何其他地方引用它。这样可以消除额外的 HTTP 请求和相关的延迟。只有在页面加载时无法确定所需数据时才需要 AJAX 调用。 - Tgr
我正在使用MVC,所以不幸的是这并不适用。 - Dr. Frankenstein
我看不出这与MVC有什么关系。您可以通过某种方式(无论是MVC还是其他方式)将用户数据放入HTTP响应中。您可以选择将用户ID放入原始HTTP响应(页面的HTML代码)或稍后的响应(AJAX结果的XML / JSON /等代码)。从结构上看,这两种类型的响应操作是相同的;如果您可以在一个方面使用MVC,则可以在另一个方面使用它。 - Tgr

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