使用组件输入更新模板
Updating a template with a component input
前言:我是 Meteor、Angular 和 Typescript 的新手,所以这里某处很有可能出现 XY 问题。
我正在使用 Meteor 和 Angular 2(使用 angular2-meteor 包)开发一个简单的项目管理应用程序,其中结构(目前)由具有事件的项目组成。一个视图是项目列表。单击项目会显示项目详细信息的模式,包括项目事件列表。因此,三个组件:ProjectList
、ProjectDetails
和 ProjectEventsList
。 ProjectDetails
使用 Session
变量来了解要显示的项目,这很有效。但是,在为单击的第一个项目创建后,模式中的事件列表不会更新。
ProjectEventsList.ts
import {Component, View} from 'angular2/core';
import {MeteorComponent} from 'angular2-meteor';
import {ProjectEvents} from 'collections/ProjectEvents';
@Component({
selector: 'projectEventsList',
inputs: ['projectId']
})
@View({
templateUrl: '/client/projectEventsList/projectEventsList.html'
})
export class ProjectEventsList extends MeteorComponent {
projectEvents: Mongo.Cursor<ProjectEvent>;
projectId: string;
constructor() {
super();
this.subscribe('projectEvents', this.projectId, () => {
this.autorun(() => {
this.projectEvents = ProjectEvents.find({projectId: this.projectId});
}, true);
});
}
}
据我了解(虽然我可能离这里很远),我很难让 autorun
自动 运行。我试过在 projectId
上放置 getter 和 setter,当我点击一个项目时它确实会更新,但是 autorun
中的代码不会 运行 第一次点击后。我尝试过的事情:
- 正在切换
subscribe()
和 autorun()
的嵌套。
- Adding/removing
subscribe()
和 autorun()
的自动绑定参数。我真的不明白那是什么意思。
将订阅代码移动到 projectId
上的 setter:
private _projectId: string = '';
get projectId() {
return this._projectId;
}
set projectId(id: string) {
this._projectId = id;
this.subscribe('projectEvents', this._projectId, () => {
this.projectEvents = ProjectEvents.find({projectId: this._projectId});
}, true);
}
当我这样做时,列表停止显示任何项目。
如果这一切看起来应该可行,我会为 post 创建一个小测试用例,但我希望这里的某些内容对于知道的人来说显然是错误的。谢谢!
this.subscribe()
和 this.autorun()
似乎不是 Angular 组件 class 的一部分。如果这是一个外部库,您可能需要在 Angular 区域中显式 运行 它以便更改检测工作:
constructor(private zone: NgZone) {
this.subscribe('projectEvents', this.projectId, () => {
this.autorun(() => {
zone.run(() => {
this.projectEvents = ProjectEvents.find({projectId: this.projectId});
});
}, true);
});
}
如果您想订阅组件本身触发的事件,请使用 host-binding
@Component(
{selector: 'some-selector',
host: {'projectEvents': 'projectsEventHandler($event)'}
export class SomeComponent {
projectsEventHandler(event) {
// do something
}
}
我最终使 setter 方法起作用,如下所示。感觉很笨重,所以我希望有一种更简洁的方法来做到这一点,但下面的方法现在对我有用(即,当父组件(ProjectList)发送一个新的 projectId
到输入。
ProjectEventsList.ts
import {Component, View} from 'angular2/core';
import {MeteorComponent} from 'angular2-meteor';
import {ProjectEvents} from 'collections/ProjectEvents';
@Component({
selector: 'projectEventsList',
inputs: ['projectId']
})
@View({
templateUrl: '/client/projectEventsList/projectEventsList.html'
})
export class ProjectEventsList extends MeteorComponent {
projectEvents: Mongo.Cursor<ProjectEvent>;
set projectId(id: string) {
this._projectId = id;
this.projectEventsSub = this.subscribe('projectEvents', this._projectId, () => {
this.projectEvents = ProjectEvents.find({projectId: this._projectId}, {sort: { startDate: 1 }});
}, true);
}
get projectId() {
return this._projectId;
}
constructor() {
super();
this.subscribe('projectEvents', this.projectId, () => {
this.projectEvents = ProjectEvents.find({projectId: this.projectId});
}, true);
}
}
前言:我是 Meteor、Angular 和 Typescript 的新手,所以这里某处很有可能出现 XY 问题。
我正在使用 Meteor 和 Angular 2(使用 angular2-meteor 包)开发一个简单的项目管理应用程序,其中结构(目前)由具有事件的项目组成。一个视图是项目列表。单击项目会显示项目详细信息的模式,包括项目事件列表。因此,三个组件:ProjectList
、ProjectDetails
和 ProjectEventsList
。 ProjectDetails
使用 Session
变量来了解要显示的项目,这很有效。但是,在为单击的第一个项目创建后,模式中的事件列表不会更新。
ProjectEventsList.ts
import {Component, View} from 'angular2/core';
import {MeteorComponent} from 'angular2-meteor';
import {ProjectEvents} from 'collections/ProjectEvents';
@Component({
selector: 'projectEventsList',
inputs: ['projectId']
})
@View({
templateUrl: '/client/projectEventsList/projectEventsList.html'
})
export class ProjectEventsList extends MeteorComponent {
projectEvents: Mongo.Cursor<ProjectEvent>;
projectId: string;
constructor() {
super();
this.subscribe('projectEvents', this.projectId, () => {
this.autorun(() => {
this.projectEvents = ProjectEvents.find({projectId: this.projectId});
}, true);
});
}
}
据我了解(虽然我可能离这里很远),我很难让 autorun
自动 运行。我试过在 projectId
上放置 getter 和 setter,当我点击一个项目时它确实会更新,但是 autorun
中的代码不会 运行 第一次点击后。我尝试过的事情:
- 正在切换
subscribe()
和autorun()
的嵌套。 - Adding/removing
subscribe()
和autorun()
的自动绑定参数。我真的不明白那是什么意思。 将订阅代码移动到
projectId
上的 setter:private _projectId: string = ''; get projectId() { return this._projectId; } set projectId(id: string) { this._projectId = id; this.subscribe('projectEvents', this._projectId, () => { this.projectEvents = ProjectEvents.find({projectId: this._projectId}); }, true); }
当我这样做时,列表停止显示任何项目。
如果这一切看起来应该可行,我会为 post 创建一个小测试用例,但我希望这里的某些内容对于知道的人来说显然是错误的。谢谢!
this.subscribe()
和 this.autorun()
似乎不是 Angular 组件 class 的一部分。如果这是一个外部库,您可能需要在 Angular 区域中显式 运行 它以便更改检测工作:
constructor(private zone: NgZone) {
this.subscribe('projectEvents', this.projectId, () => {
this.autorun(() => {
zone.run(() => {
this.projectEvents = ProjectEvents.find({projectId: this.projectId});
});
}, true);
});
}
如果您想订阅组件本身触发的事件,请使用 host-binding
@Component(
{selector: 'some-selector',
host: {'projectEvents': 'projectsEventHandler($event)'}
export class SomeComponent {
projectsEventHandler(event) {
// do something
}
}
我最终使 setter 方法起作用,如下所示。感觉很笨重,所以我希望有一种更简洁的方法来做到这一点,但下面的方法现在对我有用(即,当父组件(ProjectList)发送一个新的 projectId
到输入。
ProjectEventsList.ts
import {Component, View} from 'angular2/core';
import {MeteorComponent} from 'angular2-meteor';
import {ProjectEvents} from 'collections/ProjectEvents';
@Component({
selector: 'projectEventsList',
inputs: ['projectId']
})
@View({
templateUrl: '/client/projectEventsList/projectEventsList.html'
})
export class ProjectEventsList extends MeteorComponent {
projectEvents: Mongo.Cursor<ProjectEvent>;
set projectId(id: string) {
this._projectId = id;
this.projectEventsSub = this.subscribe('projectEvents', this._projectId, () => {
this.projectEvents = ProjectEvents.find({projectId: this._projectId}, {sort: { startDate: 1 }});
}, true);
}
get projectId() {
return this._projectId;
}
constructor() {
super();
this.subscribe('projectEvents', this.projectId, () => {
this.projectEvents = ProjectEvents.find({projectId: this.projectId});
}, true);
}
}