Javascript Ajax设计/重构在呈现新内容(如列表项和div)时提供帮助

Javascript Ajax设计/重构在呈现新内容(如列表项和div)时提供帮助,javascript,ajax,templates,refactoring,duplication,Javascript,Ajax,Templates,Refactoring,Duplication,我总是在复制标记时遇到这种代码味道,我不确定如何修复它。下面是一个典型的用例场景: 假设我们想对某类文章发表评论。在这篇文章下面,我们看到了一堆评论。这些是与原始页面请求一起添加的,由模板引擎生成(在我的例子中是Freemarker,但它可以是PHP或任何东西) 现在,每当用户添加注释时,我们都希望创建一个新的li元素,并将其插入当前页面的注释列表中。假设这个li包含一系列的东西,比如: 用户的化身 他们的名字 单击他们的个人资料或向他们发送私人消息的链接 他们写的文本 他们写评论的日期 如果当

我总是在复制标记时遇到这种代码味道,我不确定如何修复它。下面是一个典型的用例场景:

假设我们想对某类文章发表评论。在这篇文章下面,我们看到了一堆评论。这些是与原始页面请求一起添加的,由模板引擎生成(在我的例子中是Freemarker,但它可以是PHP或任何东西)

现在,每当用户添加注释时,我们都希望创建一个新的li元素,并将其插入当前页面的注释列表中。假设这个li包含一系列的东西,比如:

  • 用户的化身
  • 他们的名字
  • 单击他们的个人资料或向他们发送私人消息的链接
  • 他们写的文本
  • 他们写评论的日期
  • 如果当前登录的用户具有执行这些操作的权限,则会出现一些“编辑”和“删除”链接/按钮
  • 现在,所有这些都已经写在我们最初生成页面的模板中了。。。所以现在我们必须在Javascript中复制它

    当然,我们可以使用另一种模板语言——比如Jquery的模板插件——来减轻生成和附加这个新li块的痛苦。。。但是,我们仍然会得到重复的html标记,这与我们的html标记略有不同,因为我们不能使用宏或模板语言提供的其他便利


    那么,我们如何重构复制呢?这是可能的,还是我们只能忍受?用于解决此问题的最佳做法是什么?

    这是一个常见问题,随着UI复杂性的增加,以及必须在服务器和客户端模板上进行更改,此问题变得更加明显。通过在客户端和服务器端使用相同的模板标记,可以解决此问题。模板处理器必须同时使用JavaScript和服务器端语言编写

    另外两种解决方案比上述方法更干净,但都有自己的问题:

    • 一切都做在客户端
    • 在服务器端执行所有操作
    如果所有标记生成都是在客户端完成的,那么服务器的行为或多或少像一个web服务,它只以适合应用程序的任何格式发回数据。JSON和XML是目前大多数web服务非常流行的格式。客户端总是生成必要的HTML和JS。如果采用这种方法,必须很好地定义客户机和服务器之间的边界。由于客户端对服务器上发生的情况了解有限,这意味着必须定义正确的错误代码。状态管理将变得更加困难,因为大多数/所有服务器交互将异步进行。使用此方法添加注释的示例如下所示:

    $('#add-comment').click(function() {
        var comment = $('#comment-box').text();
        $.ajax('http://example.com/add', {
            success: function() {
                addCommentRow(comment);
            },
            ...
        });
    });
    
    function addCommentRow(comment) {
        var user = currentUser().name;
    
        var html = "<li><b>{user}</b> says {comment}</li>";
        html = html.replace("{user}", user).replace("{comment}", comment);
    
        var item = $('<li>').html(html);
        $('#comments').append(item);
    }
    

    虽然这在客户端看起来比以前的方法更干净,但我们刚刚将标记生成移到了服务器端。然而,如果应用程序不像谷歌地图那样非常AJAXy,那么这种方法可能更容易使用。同样,这是一个应用程序有多复杂的问题,也许维护状态客户端对您来说是必要的,在这种情况下,您可能希望使用前面的方法。

    这是一个有趣的问题,我不确定如何回答它,但有两件事立即浮现在脑海中。对于用javascript实现的服务器,coffeekup允许在客户端和服务器端使用相同的模板(但并不认为这是一个好的解决方案)。否则,您可以简单地
    .clone()
    一个现有的
  • 并填充新数据。服务器端模板可以为此目的生成一个特殊的隐藏div——我不觉得这很混乱,它发出的信号是:“看,这是要被重用的!”我甚至不知道coffeekup是什么。。。但是我使用的是Tomcat,所以我怀疑这是否有帮助;)。clone()是一个有趣的选择。我想我可以隐藏模板并将其填充到ul元素的按钮上。如果我这样做的话,我必须向每个标记添加更多的id或类,但这不是一个坏的解决方案。这比使用jquery的模板插件更好。我来试试,看看有多麻烦。jquery模板的一个好处是它很容易做到——它只是复制了代码。感谢您编写响应。第二种选择可能会更好一些。至少这让我可以重用freemarker模板代码,所以我只需要在一个地方修改它。现在,我做的一切都是客户端的,我一直坚持把JSON发送到客户端,就像你的第一个选择一样,让我告诉你——这简直是地狱。我的应用程序实际上非常复杂,而且总是变得越来越复杂。这是不可持续的。至于你的帖子的开头,有什么真正实用的解决方案可以在客户端使用freemarker?哪种平台允许将同一模板用于两者?还有,我可以在哪里了解协调wire协议(JSON专用)与发送html片段的优缺点?这样,如果我决定采用选项2,我就能意识到潜在的问题。我还希望尽可能保持一致性,这样我就不会让客户机/服务器上的ajax以上百种不同的方式进行操作。我想创建一些约定,以便每种类型的ajax调用都使用相同的约定和模式。这将大大简化事情。事实上,我不知道第二种选择是否真的有效。如果在呈现内容之前需要检查结果,该怎么办?如果我预先呈现html,javascript无法避免添加它(如果不应该添加的话)。如果我发回JSON,至少我可以检查一个变量,看看它是否应该做任何事情。吼叫声我也不确定这是否有效。我很沮丧,因为一些很平常的事情却很难处理,这是不必要的。我在睡觉的时候考虑了很多。。。真恶心。我猜是d
    $('#add-comment').click(function() {
        $.ajax('http://example.com/add', {
            success: function(response) {
                $('#comments').html(response);
            },
            ...
        });
    });