我是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;相反,新的结果应该是:
这给了我说错误。
这可能是愚蠢的,但由于我是流星的真正新手,我似乎无法理解什么是错的,如果你能帮助我,我会很高兴。
提前谢谢。
修改 在我的原始项目中,我使用表单直接从页面添加/删除条目。在这个测试项目中,我删除了所有不必要的东西,以尽可能简单地使用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}
答案 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>
然而,这揭示了可能是根本问题,洪波的答案解决了这个问题。