Angular2-meteor - 在subscribe函数中使用sort()后的变量未定义

时间:2016-01-15 19:39:41

标签: mongodb meteor angular angular2-meteor

我是Meteor和angular2-meteor软件包的新手,我正在努力学习如何使用它们制作精良的" Socially"在这里找到的应用教程:Socially turorial

在尝试我在那里看到的关于发布/订阅功能时,我发现了一个我不知道如何解决的问题。为了说清楚,我已经用这种结构做了一个非常简单的项目:

/typings/test.d.ts

interface Test {    
    _id?: string;
    num: number;
}

/collections/tests.ts

export var Tests = new Mongo.Collection<Test>('tests');

/server/main.ts

import './tests';

/server/test.ts - 只是发布所有内容

import {Tests} from 'collections/tests'; 

Meteor.publish('tests', function() {
    return Tests.find();
});

/client/app.ts - 订阅排序结果

import {Component, View} from 'angular2/core';

import {bootstrap} from 'angular2-meteor';

import {MeteorComponent} from 'angular2-meteor';

import {Tests} from 'collections/tests';

@Component({
    selector: 'app'
})

@View({
    templateUrl: 'client/app.html'
})

class Socially extends MeteorComponent {
    tests: Mongo.Cursor<Test>;

    constructor(){
        super();      
        this.subscribe('tests', () => {
            this.tests = Tests.find({}, {sort: {num: -1}});
        }, true);
    }
}

bootstrap(Socially);

/client/app.html - 一个简单的ngFor,显示结果

<div>
    <ul>
        <li *ngFor="#test of tests">
            <p>{{test._id}}</p>
            <p>{{test.num}}</p>
        </li>
    </ul>
</div>

如果我使用Mongo控制台插入或删除数据库中的条目,一切正常。如果我更新现有条目而不更改订单,则同样如此。但是,如果我尝试更新其中一个已经存在的条目,将更高的数字放入其数字&#34; num&#34;在他们切换位置的字段中,应用程序停止正常工作,浏览器控制台说:

  

EXCEPTION:TypeError:l_test0在[{{test._id}}的社交@ 3:15中未定义]

例如,如果我有:

  • id:1 - num:6

  • id:2 - num:5

  • id:3 - num:4

然后我尝试使用&#34; num&#34;更新条目4 put&#34; num&#34;相反,新的结果应该是:

  • id:3 - num:7
  • id:1 - num:6
  • id:2 - num:5

这给了我说错误。

这可能是愚蠢的,但由于我是流星的真正新手,我似乎无法理解什么是错的,如果你能帮助我,我会很高兴。

提前谢谢。

修改 在我的原始项目中,我使用表单直接从页面添加/删除条目。在这个测试项目中,我删除了所有不必要的东西,以尽可能简单地使用mongo控制台:

  

db.tests.insert({_ id:1,num:6})

     

db.tests.insert({_ id:2,num:5})

     

db.tests.insert({_ id:3,num:4})

     

db.tests.update({_ id:3},{$ set:{num:7}})

如果我这样做:

  

db.tests.find()

它显示:

  

{&#34; _id&#34; :1,&#34; num&#34; :6}

     

{&#34; _id&#34; :2,&#34; num&#34; :5}

     

{&#34; _id&#34; :3,&#34; num&#34; :7}

2 个答案:

答案 0 :(得分:2)

更新:检查here,错误已修复,因为angular2-meteor@0.5.1!您现在可以使用Mongo.Cursor

问题在于,当使用sort并且列表发生变化时,您现在无法将tests:Mongo.Cursor<Test>*ngFor一起使用。 *ngFor在angular2-meteor中不完全支持Mongo.Cursor。所以你需要使用纯Angular 2方式。

首先需要fetch()并使用Array<Test>,否则当列表或列表顺序发生变化时会显示此错误:

  

无法阅读财产&#39; XXX&#39;未定义的

所以最终的工作代码是这样的:

<div *ngFor="#test of tests">

</div>

// here you cannot use tests:Mongo.Cursor<Test>
tests:Array<Test>;
constructor() {
    super();
}
ngOnInit()
{
    this.subscribe('tests', () => {
        // autorun makes sure it get latest data
        this.autorun(() => {
            // here you need fetch first
            this.tests = Tests.find({}, {sort: {num: -1}}).fetch();
        }, true);
    });
}

请参阅github上的issue

答案 1 :(得分:1)

我希望有更好的答案,但我遇到了同样的问题并尝试了一些事情。

我发现如果我在自动运行中向光标添加一个观察者,那么一切都按预期运行:

this.tests.observeChanges({changed: () => {
    this.tests = Tests.find({}, {sort: {num: -1}});
}})

根据我一直在阅读的所有内容,看起来这不应该是必要的,但它对我有用。

为了防止它尝试在短暂结束undefined的光标中显示文档,我添加了ngIf

<li *ngFor="#test of tests" *ngIf="test">

修改

我一直遇到一些难以确定的问题。阅读this issue on ngFor and ngIf之后,我猜测它是因为我在同一元素上有ngFor和ngIf,显然不支持。相反,他们建议将ngIf移至封闭的<template>标记:

<template *ngIf="tests">
    <li *ngFor="#test of tests">
</template>

然而,这揭示了可能是根本问题,洪波的答案解决了这个问题。