【问题标题】:Is there a cleaner way to handle Express rendering differently for AJAX posts vs HTML form posts?有没有更简洁的方法来处理 AJAX 帖子和 HTML 表单帖子的快速渲染?
【发布时间】:2014-05-26 10:41:03
【问题描述】:

我有一个非常基本的 HTML 表单,我正在使用 jQuery 的 AJAX 发布功能来获取一些信息,具体取决于数据库插入是成功还是失败。

我的代码目前正在执行以下操作,我仅在通过 AJAX 发布时将 ajax 发布变量设置为 true 以区分来源。

app.post("/mypath", function (req, res) {
    var post = req.body;

    if (post.ajax) {
        console.log(post.ajax, "posting as ajax");
    }

    if (post.ajax) {
        res.json({data: "Woah! You posted as ajax."});
    }
    else {
        // If posting via HTML form, send the user where they need to go
        res.redirect("someview");
    }
});

我真正担心的是,我不希望最终用户看到带有纯文本 JSON 的页面,但是当我支持 JavaScript 时,我想要一些 JSON 数据,以便通知用户成功/失败。

有什么办法可以让这个更干净吗?我有 3 个地方必须在那个应用程序路径中进行条件渲染。

我正在使用 Express 3.x

【问题讨论】:

    标签: javascript jquery ajax json express


    【解决方案1】:

    当然。只要您的客户端代码适当地设置了Accept 标头,您就可以使用res.format,例如:

    res.format({
        html: function() {
            res.redirect('someview');
        },
        json: function() {
            res.json({data: "You expected JSON? You got JSON!"});
        }
    });
    

    【讨论】:

    • 我认为这可以做到,我只需要玩弄它以使我的所有异步代码都能正常工作。谢谢!
    【解决方案2】:

    看看this post我不久前写的。我写了一个助手,它会自动在 express 中呈现完整或部分视图。

    关键是要创建这样的翡翠视图:(不幸的是翡翠视图是预编译的,你不能将变量传递给include,也不能有条件地调用extends,所以我们需要这个“胶水”文件。你会明白为什么。)

    // home_full.jade
    
    extends layout  
    block content  
        include home
    

    它扩展了布局文件并包含一个局部视图。该视图充当真实视图和布局文件之间的粘合剂。这些中间视图总是以“_full.jade”结尾。

    接下来我创建了自己的小中间件函数,将帮助程序添加到req

    app.use(function (req, res, next) {  
        res.renderView = function (viewName, viewModel) {
            res.render(viewName + req.xhr ? null : '_full', viewModel);
            next();
        };
    });
    

    它被称为renderView,它为我们执行 xhr 逻辑。而不是使用req.render 渲染视图...

    res.render('home' + req.xhr ? null : '_full', viewModel);
    

    ...您只需调用req.renderView 并传入视图名称:

    res.renderView('home');
    

    现在,如果请求是整页请求,那么我们将发回完全编译的视图、布局和所有内容。如果设置了 ajax 请求标头(大多数客户端库(如 JQuery 和其他库)都会为您设置),那么我们将只发回部分视图并让客户端填充页面上的适当区域:)

    PS - 如果您需要将视图与其他 JSON 数据一起发回,您可以使用我的辅助函数的扩展版本。示例:

    res.renderView = function (viewName, viewModel) {
        if (!req.xhr) {
            res.render(viewName + '_full', viewModel);
        } else {
            res.render(viewName, viewModel, function (err, view) {
                if (err) return next(err);
                res.json({
                    title: viewModel.title || "Untitled | CodeTunnel.com",
                    bannerText: viewModel.bannerText || "CodeTunnel.com",
                    view: view,
                    url: req.url
                });
            });
        }
    };
    

    显然您会调整res.json 调用以满足您自己的需求。在上面的实现中,我需要一个 JSON 对象,其中包含页面标题、要在页面横幅中显示的文本、作为对象上的字符串属性的视图标记以及请求 URL。然后我会在客户端使用这些数据来渲染局部视图,以及更新页面标题和客户端上的其他内容。

    【讨论】:

    • 我认为对于我正在尝试做的事情来说太复杂了。
    猜你喜欢
    • 2012-10-02
    • 2018-12-02
    • 2012-05-15
    • 2019-06-10
    • 2017-07-23
    • 2012-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多