聚合函数在页面刷新时重复 ng-repeat 中的项目。需要弄清楚如何停止重复。 Angularjs Mongodb 猫鼬

Aggregate function duplicates items in ng-repeat on page refresh. Need to figure out how to stop the duplication. Angularjs Mongodb mongoose

我在集合中有一些项目 运行 通过此聚合找到具有平均评级的项目,并在它们尚未被评论/评级时找到它们。

它有效,但现在每次我刷新页面时,它都会在 bourbon 集合中的每个项目的 ng-repeat 中重复显示。 bourbon 系列中的实际物品数量没有变化。我该如何阻止呢? 服务器端: 波旁模式:

'use strict';

var mongoose = require('mongoose'),
    BourbonSchema = null;

module.exports = mongoose.model('Bourbon', {
    name:  {type: String, required: true},
    blog:  {type: String, required: true},
    photo: {type: String, required: true, default:'http://aries-wineny.com/wp-content/uploads/2014/09/woodford-reserve.jpg'},
    location: {type: String, required: true},
    distillery: {type: String, required: true},
    comments: [{type: mongoose.Schema.ObjectId, ref: 'Comments'}],
    rating : {type: Number}
});

var Bourbon = mongoose.model('Bourbon', BourbonSchema);
module.exports = Bourbon;

comment/rating 架构:

'use strict';

var mongoose = require('mongoose');

module.exports = mongoose.model('Comment', {
    bourbonId:   {type: mongoose.Schema.ObjectId, ref: 'Bourbon'},
    userId:   {type: mongoose.Schema.ObjectId, ref: 'User'},
    text:     {type: String, required: true},
    createdAt: {type: Date,  required: true, default: Date.now},
    rating  : {type: Number, required: true},
    votes:     {type: Number, default: 0}
});

聚合函数:

'use strict';

var Bourbon = require('../../../models/bourbon'),
    Comment = require('../../../models/comment'),
    DataStore = require('nedb'),
    db = new DataStore(),
    async = require('async');

module.exports = {
    description: 'Get Bourbons',
    notes: 'Get Bourbons',
    tags: ['bourbons'],
    handler: function(request, reply){

        async.series(
            [
                function(callback){
                    Bourbon.find({},function(err,results){
                        //if (err) callback(err);
                        async.eachLimit(results,10,function(result,callback){
                            var plain = result.toObject();
                            plain.bourbonId = plain._id.toString();
                            plain.avgRating = 0;
                            delete plain._id;

                            db.insert(plain,callback);
                        },callback);
                    });
                },

                function(callback){
                    Comment.aggregate(
                        [
                            {$group:{
                                _id: '$bourbonId',
                                avgRating:{$avg:'$rating'}
                            }}
                        ],
                        function(err,results){
                            async.eachLimit(results,10,function(result,callback){
                                db.update(
                                    {bourbonId: result._id.toString()},
                                    {$set: {avgRating: result.avgRating}},
                                    callback                   
                                );
                            },callback);                 
                        }
                    );
                }
            ],

            function(err){
                //if (err) callback(err);
                db.find({}, {_id: 0}, function(err, bourbons){
                    console.log('DOOOOCS', bourbons);
                    reply ({bourbons:bourbons});
                });
            });
    }
};

客户端

factory:

(function(){
    'use strict';

    angular.module('hapi-auth')
        .factory('Bourbon', ['$http', function($http){

            function create(bourbon){
                return $http.post('/admin', bourbon);
            }

            function all(){
                return $http.get('/admin');
            }

            return {create:create, all:all};
        }]);
})();

控制器:

(function(){
    'use strict';

    angular.module('hapi-auth')
        .controller('AdminCtrl', ['$scope', 'Bourbon', function($scope, Bourbon){
            //$scope.blog.photo = [];
            $scope.bourbon = {};
            $scope.bourbons = [];

            Bourbon.all().then(function(res){
                $scope.bourbons = res.data.bourbons;
                console.log(res.data.bourbons);
            });

            $scope.createBourbon = function(bourbon){
                console.log('BOURBB', bourbon);
                Bourbon.create(bourbon).then(function(res){
                    console.log('bourboonnnn', res.data);
                    $scope.bourbons.push(res.data);

                });
            };


        }]);
})();

翡翠:

.row
   .small-4.columns
   .small-4.columns
      .review
         .insertContainer(ng-repeat='bourbon in bourbons')
            .adminName Name: {{bourbon.name}}
            img.bourbonImg(src='{{bourbon.photo}}')
            .adminBlog {{bourbon.blog.slice(0,200)}} ...
   .small-4.columns

尝试在页面刷新时停止重复波旁威士忌集合中的项目.... 不确定我是否需要在这里实施某种替换方法..现在有点卡住..

这是控制器/聚合函数中的控制台日志returns:

DOOOOCS [ { name: 'woodford reserve',
    location: 'kentucky',
    distillery: 'woodford',
    blog: 'fjkd;asdljfkld;ksdfj',
    __v: 0,
    comments: [],
    photo: 'http://aries-wineny.com/wp-content/uploads/2014/09/woodford-reserve.jpg',
    bourbonId: '54c2aa5556267e0000b5618c',
    avgRating: 0 },
  { name: 'woodford reserve',
    location: 'kentucky',
    distillery: 'woodford',
    blog: 'fjkd;asdljfkld;ksdfj',
    __v: 0,
    comments: [],
    photo: 'http://aries-wineny.com/wp-content/uploads/2014/09/woodford-reserve.jpg',
    bourbonId: '54c2aa5556267e0000b5618c',
    avgRating: 0 } ]

每当此函数为 运行... 时,它似乎都会复制 Bourbons 集合中的每个项目,它 运行 在页面刷新时作为 Bourbon.all 在 angular 控制器。

这是该系列中的波本威士忌,在它 运行 之前通过聚合:

{
    "_id" : ObjectId("54c2aa5556267e0000b5618c"),
    "name" : "woodford reserve",
    "location" : "kentucky",
    "distillery" : "woodford",
    "blog" : "fjkd;asdljfkld;ksdfj",
    "comments" : [],
    "photo" : "http://aries-wineny.com/wp-content/uploads/2014/09/woodford-reserve.jpg",
    "__v" : 0
}

更新了 jade w/ track by:

.row
   .small-4.columns
   .small-4.columns
      .review
      .insertContainer(ng-repeat='bourbon in bourbons | unique: bourbon.bourbonId | filter: query')

            .adminName Name: {{bourbon.name}}
            img.bourbonImg(src='{{bourbon.photo}}')
            .adminBlog {{bourbon.blog.slice(0,200)}} ...
   .small-4.columns

这允许项目在第一次加载时显示,但在任何刷新/重新加载时,我现在收到此错误:

Error: [ngRepeat:dupes] Duplicates in a repeater are not allowed. Use 'track by' expression to specify unique keys. Repeater: bourbon in bourbons track by bourbon.bourbonId | filter:query, Duplicate key: 54c2aa5556267e0000b5618c, Duplicate value: {"name":"woodford reserve","location":"kentucky","distillery":"woodford","blog":"fjkd;asdljfkld;ksdfj","__v":0,"comments":[],"photo":"http://aries-wineny.com/wp-content/uploads/2014/09/woodford-reserve.jpg","bourbonId":"54c2aa5556267e0000b5618c","avgRating":0}
http://errors.angularjs.org/1.3.8/ngRepeat/dupes?p0=bourbon%20in%20bourbons…C%22bourbonId%22%3A%2254c2aa5556267e0000b5618c%22%2C%22avgRating%22%3A0%7D
    at http://localhost:7070/vendor/angular/angular.js:63:12
    at ngRepeatAction (http://localhost:7070/vendor/angular/angular.js:24483:21)
    at Object.$watchCollectionAction [as fn] (http://localhost:7070/vendor/angular/angular.js:14092:13)
    at Scope.$digest (http://localhost:7070/vendor/angular/angular.js:14225:29)
    at Scope.$apply (http://localhost:7070/vendor/angular/angular.js:14488:24)
    at done (http://localhost:7070/vendor/angular/angular.js:9646:47)
    at completeRequest (http://localhost:7070/vendor/angular/angular.js:9836:7)
    at XMLHttpRequest.requestLoaded (http://localhost:7070/vendor/angular/angular.js:9777:9)

这些是在浏览器控制台中返回的 bourbon 项目。它们都具有相同的 bourbonId,从索引 0 开始。唯一过滤器现在返回 2 个 bourbon 对象(原始对象和一个重复对象?)而不是所有对象...:

[对象,对象,对象,对象,对象]0:对象$$hashKey:"object:6"v:0avgRating:4blog:"fjkd;asdljfkld;ksdfj"bourbonId:“54c2aa5556267e0000b5618c"comments: Array[0]distillery: "woodford"location: "kentucky"name: "woodford reserve"photo: "http://aries-wineny.com/wp-content/uploads/2014/09/woodford-reserve.jpg"__proto: Object1: Object__v: 0avgRating: 4blog: "fjkd;asdljfkld;ksdfj"bourbonId: "54c2aa5556267e0000b5618c"comments: Array[0]distillery: "woodford"location: "kentucky"name: "woodford reserve"photo: "http://aries-wineny.com/wp-content/uploads/2014/09/woodford-reserve.jpg"proto: Object2: Object$$hashKey: "object:7"v: 0avgRating: 0blog: "fjkd;asdljfkld;ksdfj"bourbonId: "54c2aa5556267e0000b5618c"comments: Array[0]length: 0__proto: Array[0]distillery: "woodford"location: "kentucky"name: "woodford reserve"photo: "http://aries-wineny.com/wp-content/uploads/2014/09/woodford-reserve.jpg"proto: Object3: Object__v: 0avgRating: 0blog: "fjkd;asdljfkld;ksdfj"bourbonId: "54c2aa5556267e0000b5618c"comments: Array[0]length: 0__proto__: Array[0]distillery: "woodford"location: "kentucky"name: "woodford reserve"photo: "http://aries-wineny.com/wp-content/uploads/2014/09/woodford-reserve.jpg"proto: Object4: Object__v: 0avgRating: 0blog: "fjkd;asdljfkld;ksdfj"bourbonId: "54c2aa5556267e0000b5618c"comments: Array[0]length: 0__proto__: Array[0]distillery: "woodford"location: "kentucky"name: "woodford reserve"photo: "http://aries-wineny.com/wp-content/uploads/2014/09/woodford-reserve.jpg"proto: Objectlength: 5__proto__: Array[ 0]


我想我已经将其缩小为服务器端的问题,在上面列出的控制器/聚合中。我需要找到一种方法来替换更新的文档,而不是每次在客户端/浏览器上调用 Bourbon.all / 运行 时都创建一个新文档......现在尝试解决它。任何提示,非常感谢。

这似乎是服务器端的问题,通过 $index 添加轨道将解决该问题。

ng-repeat='bourbon in bourbons track by $index

但问题是,它会显示重复的记录。

最好使用 AngularUI angular.unique filter

首先从 link 添加 JS,然后在应用依赖项中添加 'ui.filters' 模块。

ng-repeat='bourbon in bourbons | unique:'bourbonId'

希望这能解决您的问题。

谢谢。

这似乎只是一个过于字面的例子。您最终会在每个请求上得到重复的输出,因为这就是结果来自的商店的范围。

所以不是这个:

'use strict';

var Bourbon = require('../../../models/bourbon'),
    Comment = require('../../../models/comment'),
    DataStore = require('nedb'),
    db = new DataStore(),          // <-- globally scoped in the module :(
    async = require('async');

module.exports = {
    description: 'Get Bourbons',
    notes: 'Get Bourbons',
    tags: ['bourbons'],
    handler: function(request, reply){

        async.series(
            [
                function(callback){

最好这样做:

'use strict';

var Bourbon = require('../../../models/bourbon'),
    Comment = require('../../../models/comment'),
    DataStore = require('nedb'),
    async = require('async');

module.exports = {
    description: 'Get Bourbons',
    notes: 'Get Bourbons',
    tags: ['bourbons'],
    handler: function(request, reply){

        db = new DataStore();   // <--- Init store within request scope :)

        async.series(
            [
                function(callback){