1

前言:我是Meteor,Angular和Typescript的新手,因此在这里某处出现XY问题的可能性非常大。使用组件输入更新模板

我正在使用流星和2角(使用angular2-meteor包)一个简单的项目管理应用程序,其中结构(现在)由具有活动项目。一个视图是项目列表。点击一个项目会显示项目细节的模式,包括项目事件的列表。因此,三个组件:ProjectList,ProjectDetailsProjectEventsListProjectDetails使用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()
  • 将自动绑定参数添加到subscribe()autorun()。我真的不明白应该做什么。
  • 移动订阅代码到一个setter上projectId

    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); 
    } 
    

    当我做这个名单停止显示任何项目。

如果这一切似乎像它应该工作,我将创建一个小的测试案例后,但我希望的东西在这里将是明显错误的那些谁知道。谢谢!

回答

0

我最终得到了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); 
    } 
} 
1

this.subscribe()this.autorun()似乎并不是Angular组件类的一部分。如果这是一个外部库,你可能需要在一个角度带明确地运行它的变化检测工作:

constructor(private zone: NgZone) { 
    this.subscribe('projectEvents', this.projectId,() => { 
     this.autorun(() => { 
      zone.run(() => { 
       this.projectEvents = ProjectEvents.find({projectId: this.projectId}); 
      }); 
     }, true); 
    }); 
} 

如果你想订阅组件自身所触发的事件使用主机结合

@Component(
    {selector: 'some-selector', 
    host: {'projectEvents': 'projectsEventHandler($event)'} 
export class SomeComponent { 
    projectsEventHandler(event) { 
    // do something 
    } 
} 
+0

关于有关区域的上半年:这是不是一个概念我很熟悉,所以感谢提醒我这样的区分(即角区外运行的代码)!凉。但是,我不认为它解决了根本问题 - 自动运行永远不会自动运行。 – Trygve

+0

是的,我花了一段时间才开始理解你的问题。第二部分呢?该事件来自哪里? –

+0

'ProjectEventsList'被插入到'ProjectDetails'中: '' 我不完全确定你是什么意思的事件,但是当我在'ProjectList'中单击一个项目,它更新'ProjectDetails'并将新的输入值发送到'ProjectEventsList'。但是然后'ProjectEventsList'不对这个更新的id做任何事情。 – Trygve