父/子绑定不起作用,绑定目标设置为未知类型的对象

时间:2016-06-18 01:45:16

标签: angular

我正在尝试创建类似于此处描述的父/子绑定 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>

1 个答案:

答案 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 = "";
}