我正在尝试创建类似于此处描述的父/子绑定 https://angular.io/docs/ts/latest/tutorial/toh-pt3.html
我遇到的第一个问题是事件似乎无法触发,因此绑定不起作用。
第二个问题是我的子组件(commentList)上的输入属性的setter正在被调用,但它被设置为不属于ContentItem类型的对象。该对象不为null,未定义,并且没有名为ID的属性。
简而言之:父组件调用服务。在服务返回之前,将调用子组件中的setter并将其设置为不正确类型的对象(contentItem)。当服务在父级中返回并设置Post对象时,应该更新子级中的绑定,但不应该更新。
请参阅以下代码中的其他评论。
blogDetails(父组件)
import { Component, Input, OnInit } from '@angular/core';
import { RouteSegment, OnActivate } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { BlogService} from './../services/BlogService';
import { SessionService} from './../services/SessionService';
import { ContentItem } from '../model/model';
import { CommentList } from '../comments/commentList';
@Component({
selector: 'blog-blog-detail',
templateUrl: './app/blog/blogDetail.html',
directives:[CommentList]
})
export class BlogDetail implements OnActivate {
PostRoot = this.sessionService.PostRoot;
private Post: ContentItem;
private Content: string;
constructor(private sessionService: SessionService, private blogService: BlogService) {
//this.Post = new ContentItem();
this.Content = "";
}
routerOnActivate(data: RouteSegment)
{
let slug = data.getParam('slug');
if (slug === null || typeof slug === 'undefined')
return;
this.blogService.GetContentItemBySlug(slug, this.sessionService.CurrentSite.ID).subscribe(x => { // this line fires first
this.Post = x; // setting this should trigger the binding to update the child but it does not.
this.blogService.GetPostHtml(this.sessionService.PostRoot + this.Post.URL).subscribe((h: string) => {
this.Content = h;
});
});
}
}
blogDetail.html
<div>
<h1>this is blog detail</h1>
{{Post.Title }}
<div [innerHTML]="[Content]"></div>
</div>
<blog-comment-list [contentItem]="Post"></blog-comment-list>
commentList(子组件)
import { Component, Input, OnInit } from '@angular/core';
import { RouteSegment, OnActivate } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { BlogService} from './../services/BlogService';
import { SessionService} from './../services/SessionService';
import { ContentItem } from '../model/model';
import { Comment } from '../model/model';
@Component({
selector: 'blog-comment-list',
templateUrl: './app/comments/commentList.html'
})
export class CommentList {
private _contentItem: ContentItem;
@Input()
get contentItem()
{
return this._contentItem;
}
set contentItem(ci: ContentItem)
{
this._contentItem = ci; // this line fires immediately after blogDetail calls GetContentItemBySlug... it should be called when POST is set
this.LoadComments(this._contentItem)
}
Comments: Comment[];
constructor(private sessionService: SessionService, private blogService: BlogService) {
//this.Comments = [];
}
private LoadComments(ci: ContentItem) {
if (ci === null || typeof ci === 'undefined' || ci.ID === 0)
return;
this.blogService.GetCommentsForContentItem(ci.ID).subscribe(x => {
this.Comments = x;
});
}
}
commentList.html
<div>
<div *ngFor="let comment of Comments">
{{comment.CommentText}}
</div>
</div>
答案 0 :(得分:0)
你生活和学习。我发现新建对象在Typescript中的工作方式与在c#中的工作方式不同。显然,在创建对象时不会创建对象属性(这很奇怪......也许我应该将它们初始化为默认值)。我在构造函数中将ID设置为零,因此子类知道不会尝试调用api服务。
export class BlogDetail implements OnActivate {
PostRoot = this.sessionService.PostRoot;
Post: ContentItem;
private Content: string;
constructor(private sessionService: SessionService, private blogService: BlogService) {
this.Post = new ContentItem();
this.Post.ID = 0; // must initialize property or it will not be created on object
this.Content = "";
}