在node / express中构建数据对象并将对象传递给渲染模板

时间:2014-06-25 21:20:42

标签: javascript node.js express callback

这里有一个noob问题......但首先,有点背景信息......

我已经开始使用Express JS对应用程序进行编码了,虽然我一点一点地掌握它,但我已经碰到了一堵砖墙......

我有一个CodeIgniter背景,在CI中你可以在控制器中构建一个$ data变量,其中包含你需要传递给你将要呈现的页面的所有数据。

所以我试图在Express中做同样的事情......但我没有看到如何正确地做到这一点。

例如,

我在一个名为'routes.js'的文件中有这段代码:

//when you navigate to domain.com/test
app.get('/test', function(req, res)
{
    //object where i want to store all my data
    var data = {};

    //dynamically get the navigation menu
    navigation_model.get_menu(function(err, result){

            if(err) throw err;

            //add the result, which is an object, to the data obj
            data.navigation = result;
    });


    content_model.findAll(function(err, result){

            if(err) throw err;

            //add the result, which is an object, to the data obj
            data.content = result;
    });

    //page that i want to send the data to 
    res.render('test_view',{data: this.data});

});

我遇到的问题是,对于Node的异步性质,当我渲染页面时,我的'数据'对象仍然没有从模型中接收数据......

问题:

  1. 那么将数据输入'data'obj的最佳方法是什么?
  2. 我是否必须在回调函数内嵌入代码,在更多的回调函数中,直到我的数据obj收到数据? (感觉适得其反)
  3. 非常感谢任何帮助!

1 个答案:

答案 0 :(得分:1)

数据为空的原因是因为函数getMenu& findAll是异步的,即渲染调用在getMenu&之前发生。 findAll能够完成其执行并填充数据中适当的值。

修复它的一种方法是在第一个函数的回调中调用第二个函数,依此类推。

navigation_model.get_menu(function(err, result){

    if(err) throw err;

    //add the result, which is an object, to the data obj
    data.navigation = result;

    content_model.findAll(function(err, result){

            if(err) throw err;

            //add the result, which is an object, to the data obj
            data.content = result;

            res.render('test_view',{data: this.data});
    });

 });

更好的方法是使用async库的parellel或瀑布方法来运行geMenu& amp; findAll in prallel或者一个接一个地使用waterfall然后调用render方法。