Angular2-meteor - 在订阅函数中使用排序的 find() 后变量未定义
Angular2-meteor - Variable undefined after a find() with sort in a subscribe function
我是 Meteor 和 angular2-meteor 包的新手,我正在尝试按照此处提供的制作精良的 "Socially" 应用程序教程学习如何使用它们:Socially turorial.
在试验我在那里看到的有关 Publish/Subscribe 函数的内容时,我发现了一个我不知道如何解决的问题。为了清楚起见,我用这种结构做了一个非常简单的项目:
/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 控制台在数据库中插入或删除条目,一切正常。如果我更新现有条目 而不 更改它们的顺序,情况也是一样。但是,如果我尝试更新其中一个已存在的条目,在其 "num" 字段中放置一个更高的数字,使它们切换位置,应用程序将停止正常工作,并且浏览器控制台显示:
EXCEPTION: TypeError: l_test0 is undefined in [{{test._id}} in Socially@3:15]
例如,如果我有:
id:1 - num:6
id:2 - num:5
id:3 - num:4
然后我尝试用 "num" 更新条目 4 将 "num" 改为 7,新结果应该是:
- 编号:3 - 编号:7
- 编号:1 - 编号:6
- 编号:2 - 编号:5
这是给我说的错误。
这可能很愚蠢,但由于我是 meteor 的真正新手,我似乎不明白哪里出了问题,如果你能帮助我,我会很高兴。
提前致谢。
编辑:
在我最初的项目中,我使用一个表单直接从页面 add/remove 条目。在这个测试项目中,我删除了所有不必要的东西以使其尽可能简单并使用 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()
显示:
{ "_id" : 1, "num" : 6 }
{ "_id" : 2, "num" : 5 }
{ "_id" : 3, "num" : 7 }
我希望那里有更好的答案,但我遇到了同样的问题并且一直在尝试一些事情。
我发现如果我在自动运行中向光标添加一个观察者,那么一切都会按预期运行:
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>
然而,这揭示了洪波的回答可能解决的根本问题。
更新:检查here,自angular2-meteor@0.5.1 以来该错误已修复!您现在可以使用 Mongo.Cursor
。
问题是当使用 sort
和列表更改时,您现在不能将 tests:Mongo.Cursor<Test>
与 *ngFor
一起使用。 *ngFor
不支持 Mongo.Cursor
在 angular2-meteor 中完美。所以你需要使用纯 Angular 2 方式。
首先需要fetch()
,然后使用Array<Test>
,否则列表或列表顺序改变时会报错:
Cannot read property 'XXX' of undefined
所以最终的工作代码是这样的:
<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);
});
}
参考 issue github
我是 Meteor 和 angular2-meteor 包的新手,我正在尝试按照此处提供的制作精良的 "Socially" 应用程序教程学习如何使用它们:Socially turorial.
在试验我在那里看到的有关 Publish/Subscribe 函数的内容时,我发现了一个我不知道如何解决的问题。为了清楚起见,我用这种结构做了一个非常简单的项目:
/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 控制台在数据库中插入或删除条目,一切正常。如果我更新现有条目 而不 更改它们的顺序,情况也是一样。但是,如果我尝试更新其中一个已存在的条目,在其 "num" 字段中放置一个更高的数字,使它们切换位置,应用程序将停止正常工作,并且浏览器控制台显示:
EXCEPTION: TypeError: l_test0 is undefined in [{{test._id}} in Socially@3:15]
例如,如果我有:
id:1 - num:6
id:2 - num:5
id:3 - num:4
然后我尝试用 "num" 更新条目 4 将 "num" 改为 7,新结果应该是:
- 编号:3 - 编号:7
- 编号:1 - 编号:6
- 编号:2 - 编号:5
这是给我说的错误。
这可能很愚蠢,但由于我是 meteor 的真正新手,我似乎不明白哪里出了问题,如果你能帮助我,我会很高兴。
提前致谢。
编辑: 在我最初的项目中,我使用一个表单直接从页面 add/remove 条目。在这个测试项目中,我删除了所有不必要的东西以使其尽可能简单并使用 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()
显示:
{ "_id" : 1, "num" : 6 }
{ "_id" : 2, "num" : 5 }
{ "_id" : 3, "num" : 7 }
我希望那里有更好的答案,但我遇到了同样的问题并且一直在尝试一些事情。
我发现如果我在自动运行中向光标添加一个观察者,那么一切都会按预期运行:
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>
然而,这揭示了洪波的回答可能解决的根本问题。
更新:检查here,自angular2-meteor@0.5.1 以来该错误已修复!您现在可以使用 Mongo.Cursor
。
问题是当使用 sort
和列表更改时,您现在不能将 tests:Mongo.Cursor<Test>
与 *ngFor
一起使用。 *ngFor
不支持 Mongo.Cursor
在 angular2-meteor 中完美。所以你需要使用纯 Angular 2 方式。
首先需要fetch()
,然后使用Array<Test>
,否则列表或列表顺序改变时会报错:
Cannot read property 'XXX' of undefined
所以最终的工作代码是这样的:
<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);
});
}
参考 issue github