7

プリンシパル オブジェクトのスキーマは次のとおりです。

var newsSchema = new Schema({
    headline: String,
    paragraph: String,
    imgURI: String,
    imgThumbURI: String,
    imgCaption: String,
    addedOn: Date,
    addedBy: {
        type: ObjectID,
        ref: 'usr'
    }
});
var News = mongoose.model('news', newsSchema);

...そして addedBy のスキーマ:

var usr = new Schema({
    username: String,
    avatar: {
        type: ObjectID,
        ref: 'avtr'
    },
    href: String
});
var UserModel = mongoose.model('usr', usr);

ここまでは順調ですね。すべての作品。次に、Angular クライアントでニュース オブジェクトを取得しますが、 addedBy の値は目的のオブジェクトではなく、ObjectId です。

{
    "headline":"Shocking news from the Neverland!",
    ...
    "addedBy":"520e9aac9ca114914c000003", // <-- the offender!!
    "addedOn":"2013-08-16T21:33:32.294Z",
    "_id":"520e9aac9ca114914c000001",
    "__v":0
}

このようなオブジェクトが必要な場合:

{
    "headline":"Shocking news from the Neverland!",
    ...
    "addedBy":{
        "username":"Peter"
        "avatar":{
            "src":"../images/users/avatars/avatar1.png", 
            "ststus":"happy"}
        }
    "addedOn":"2013-08-16T21:33:32.294Z",
    "_id":"520e9aac9ca114914c000001",
    "__v":0
}

そうです、プリンシパル オブジェクトが angular クライアントに送信される前に、ネストされたすべての ObjectId を (深さに関係なく) DB のそれぞれのオブジェクトに置き換えたいと考えています。私が構築している API は深くて複雑であり、Angular クライアントが Express サーバーからスコープにスローされる準備ができているオブジェクトを受信できると便利です。
次の「/ニュース」ルートを変更するにはどうすればよいですか:

app.get('/news', function(req, res, next){
    News.
        find().
        exec(function(err, nws){
            if(err) {res.writeHead(500, err.message)}
            res.send(nws);
        });
});

まさにそれを達成するために、次のようにAngularから完全な(ネストされた)オブジェクトに完全にアクセスできます:

angular.module('App', ['ngResource'])
    .controller('NewsCtrl', function($scope, $resource){
        var News = $resource('/news');
        var news = News.query();
        $scope.news = news;
    });

次に、Web サイトで次のように API にアクセスします。

<img class="avatar-img" src="{{ news[0].addedBy.avatar.src }}">

お時間をいただき、誠にありがとうございました。

4

1 に答える 1

6

@WiredPrairieが言ったように、populate関数を使用する必要がありますPopulate Mongoose Documentation

クエリは次のようになります。

app.get('/news', function(req, res, next){
    News.
        find().
        populate("addedBy").
        exec(function(err, nws){
            if(err) {res.writeHead(500, err.message)}
            res.send(nws);
        });
});

populate でできることはたくさんあります。たとえば、「addedBy」ドキュメントのユーザー名フィールドだけを表示するには、次のようにします。

populate("addedBy","username")

または、特定のフィールドを 1 つ持ちたくない場合は、次のようにします。

populate("addedBy","-username")
于 2013-08-17T05:18:57.527 に答える