Mongodb Angular2 meteor-订阅函数中带有sort的find()后未定义的变量
我是Meteor和angular2 Meteor软件包的新手,我正在努力学习如何使用它们,下面是制作精良的“社交”应用程序教程: 在试验发布/订阅函数时,我发现了一个我不知道如何解决的问题。为了明确起见,我用这种结构做了一个非常简单的项目: /typings/test.d.tsMongodb Angular2 meteor-订阅函数中带有sort的find()后未定义的变量,mongodb,meteor,angular,angular2-meteor,Mongodb,Meteor,Angular,Angular2 Meteor,我是Meteor和angular2 Meteor软件包的新手,我正在努力学习如何使用它们,下面是制作精良的“社交”应用程序教程: 在试验发布/订阅函数时,我发现了一个我不知道如何解决的问题。为了明确起见,我用这种结构做了一个非常简单的项目: /typings/test.d.ts interface Test { _id?: string; num: number; } export var Tests = new Mongo.Collection<Test>
interface Test {
_id?: string;
num: number;
}
export var Tests = new Mongo.Collection<Test>('tests');
import './tests';
/collections/tests.ts
interface Test {
_id?: string;
num: number;
}
export var Tests = new Mongo.Collection<Test>('tests');
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);
<div>
<ul>
<li *ngFor="#test of tests">
<p>{{test._id}}</p>
<p>{{test.num}}</p>
</li>
</ul>
</div>
从'angular2/core'导入{Component,View};
从“angular2 meteor”导入{bootstrap};
从“angular2 meteor”导入{MeteoComponent};
从“集合/测试”导入{Tests};
@组成部分({
选择器:“应用程序”
})
@看法({
templateUrl:'client/app.html'
})
类对组件进行社会扩展{
测试:Mongo.Cursor;
构造函数(){
超级();
this.subscribe('tests',()=>{
this.tests=tests.find({},{sort:{num:-1});
},对);
}
}
引导(社会);
/client/app.html-一个简单的ngFor,显示结果
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);
<div>
<ul>
<li *ngFor="#test of tests">
<p>{{test._id}}</p>
<p>{{test.num}}</p>
</li>
</ul>
</div>
-
{{test.\u id}}
{{test.num}
如果我使用Mongo控制台从数据库中插入或删除条目,一切正常。如果我更新一个现有条目而不更改其顺序,也是一样的。但是,如果我尝试更新其中一个已存在的条目,在其“num”字段中添加更高的数字,使其切换位置,则应用程序将停止正常工作,浏览器控制台会显示:
异常:TypeError:l_test0在中的[{test.\u id}}中未定义Socially@3:15]
例如,如果我有:
- 编号:1-编号:6
- id:2-数量:5
- id:3-数量:4
- 编号:3-编号:7
- 编号:1-编号:6
- id:2-数量:5
我希望有一个更好的答案,但我也有同样的问题,我一直在尝试一些事情 我发现,如果我在自动运行中向光标添加观察者,那么一切都会按预期运行:
this.tests.observeChanges({changed: () => {
this.tests = Tests.find({}, {sort: {num: -1}});
}})
从我所读到的一切来看,这似乎不是必要的,但对我来说确实有用
为了防止它试图在光标中显示文档,而该文档会短暂地以未定义
结束,我添加了一个ngIf
:
<li *ngFor="#test of tests" *ngIf="test">
编辑
我一直有一些难以确定的问题。在阅读之后,我猜这是因为我在同一个元素上有ngFor和ngIf,这显然是不受支持的。相反,他们建议将ngIf向上移动到一个封闭的
标签:
<template *ngIf="tests">
<li *ngFor="#test of tests">
</template>
然而,这揭示了洪波的答案所针对的根本问题。更新:检查,该错误自angular2以来已修复-meteor@0.5.1! 现在可以使用
Mongo.Cursor
问题是,当使用排序
并且列表发生更改时,您现在不能将tests:Mongo.Cursor
与*ngFor
一起使用*ngFor
在angular2 meteor中不支持Mongo.Cursor
。所以你需要使用纯角度2路
您需要先使用fetch()
并使用Array
,否则当列表或列表顺序更改时,它将显示此错误:
无法读取未定义的属性“XXX”
因此,最终的工作代码如下所示:
<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);
});
}
//这里不能使用tests:Mongo.Cursor
测试:数组;
构造函数(){
超级();
}
恩戈尼尼特()
{
this.subscribe('tests',()=>{
//自动运行确保获得最新数据
这个。自动运行(()=>{
//这是你需要先取的
this.tests=tests.find({},{sort:{num:-1}}).fetch();
},对);
});
}
请参阅github上的以进行测试,您是否可以在模板(问号)中尝试以下语法:
{{test?{u id}}
和{{test?.num}
。也许这是angular2中的一个bug,这是一个工作-around@PierreDuc谢谢你的建议。我试着按照你说的去做,错误显然已经消失了,但是现在最后更新的条目消失了,直到我再次重新加载页面(我上一个例子中的“id:3-num:7”)。嗯,你在哪里更新num值?用js还是用mongo?如果在js中,怎么做?@PierreDuc我编辑了我的原始消息来回答你的问题。现在我可以发表评论了,把这个移到这里:你不能只使用autobind参数来自动运行回调,在一个角度变化检测区域中,像这样:this.autorun(()=>{this.tests=tests.find({},{sort:{num:-1})。fetch();},true)代码>@Trygve该行只是确保您执行的工作运行i