2

動的ヘルパーを処理する外部ファイルを作成しました。これには、すべてのビューから使用できるようにしたい一連の関数が含まれています。

クエリを実行し、データベースからタグを取得している関数の中で、layout.jade ファイルで使用したい (他のすべてのビューが使用している)。コンソールでは、すべて問題ないようです。クエリはタグ オブジェクトを返しますが、奇妙な理由でオブジェクトをビューに返すことができず、「タグ」が未定義であることを示すエラー メッセージが表示されます。

これは私のファイルdynamicHelpers.jsのコードです:

exports.tags = function(req, res){
    var environment = require('../environment');
    var service = require('../service');
        service.init(environment);

    var model = service.useModel('tag');

    var query = model.Tag.find({});
    query.exec(function (err, tags) {
        if (err) {
            console.log(err);
            // do something
        }
        console.log(tags);
        return tags;
    });
}

layout.jade では、この方法でオブジェクトを取得しています (これは未定義を示しています):

p
    #{tags}

私が実際にやりたいことは、すべてのタグを「each」でループすることです。したがって、フォローアップの問題は、これが許可され、可能である場合 (「タグ」が未定義でない場合) でしょうか?

ul.tags
    each tag in #{tags}
        a(href='/tag/' + tag._id.toHexString())
            li.tag= tag.name

更新: @Linus G Thiel のソリューション (以下を参照) を試しましたが、機能しません (res.tags が未定義になります)。ミドルウェアで console.log(tags) を使用すると、オブジェクトが出力されます。ただし、以下の dynamicHelper 関数では未定義になります。res.tags が何らかの理由で dynamicHelper に渡されないようです。

dynamicHelpers.js:

exports.tags = function(req, res) {
    console.log(req.tags); <--- undefined
    return req.tags;
};

構成.js:

module.exports = function(app, express, next){
    app.configure(function() {
        // lots of more app.use functions (eg. express.cookieParser());)
        // ...

        app.use(function(req, res, next) {
            var environment = require('./environment');
            var service = require('./service');
                service.init(environment);

            var model = service.useModel('tag');

            var query = model.Tag.find({});
            query.exec(function (err, tags) {
                if (err) {
                    return next(err);
                }
                req.tags = tags;
                next();
            console.log(req.tags); <--- works fine
            });
        });
    });
};
4

3 に答える 3

4

@Exploitが彼のコメントで述べているように、tags関数は への非同期呼び出しを行い、関数が返さquery.execれた後に終了します。tagsExpress'helpersでありdynamicHelpers、非同期にすることはできないため、何らかの方法でこれをリファクタリングする必要があります。1 つの方法はreq、以前のミドルウェアまたはルートでそれを配置し、dynamicHelperそれを返す単純なものを用意することです。

dynamicHelpers.js:

exports.tags = function(req, res) {
    return req.tags;
};

ミドルウェア (すべてのルートに対してこれを行いたくない場合があります。たとえば、ルート固有のミドルウェアまたはルート パラメータの事前条件を調べることができます):

app.use(function(req, res, next) {
    var environment = require('../environment');
    var service = require('../service');
        service.init(environment);

    var model = service.useModel('tag');

    var query = model.Tag.find({});
    query.exec(function (err, tags) {
        if (err) {
            return next(err);
        }
        req.tags = tags;
        next();
    });
});
于 2012-04-20T11:25:43.837 に答える
1

他のルートのにミドルウェアを定義する必要があります

module.exports = function(app, express, next){
    app.configure(function() {

        app.use(function(req, res, next) {
            var environment = require('./environment');
            var service = require('./service');
                service.init(environment);

            var model = service.useModel('tag');

            var query = model.Tag.find({});
            query.exec(function (err, tags) {
                if (err) {
                    return next(err);
                }
                req.tags = tags;
                next();
            console.log(req.tags); <--- works fine
            });
        });

        // lots of more app.use functions (eg. express.cookieParser());)
        // ...

    });
};
于 2012-04-23T07:33:01.413 に答える