根据输入字段更新列表

时间:2017-11-24 20:58:17

标签: angular

我想根据表单字段中的输入更新简单列表。现在我有一些虚拟数据设置:

protected comments: any = [
    {
        "id": "123",
        "date": "1511545812",
        "author": "rockwcl1",
        "message": "This is a message"
    },
    {
        "id": "1232",
        "date": "1511545812",
        "author": "rockwcl1",
        "message": "This is another message"
    }
]

getComments() {
    return this.comments;
}

addComment(comment: any) {
    this.comments.push(comment);
    console.log(this.comments);
}

我的父组件:

import {Component} from '@angular/core';
import {IonicPage, NavController, NavParams} from 'ionic-angular';
import {Comment} from "../../comments/comment.service";

@IonicPage()
@Component({
    selector: 'page-event-discussion',
    templateUrl: 'event-discussion.html',
    providers: [
        Comment
    ]
})
export class EventDiscussionPage {
    event: any;
    comments: any;
    constructor(public navCtrl: NavController, public navParams: NavParams, private _commentApi: Comment) {
        this.event = this.navParams.data.event;
        this.comments = this._commentApi.getComments();
    }
}

事件discussion.html

<!-- removed some header stuff -->
<ion-content padding>
   <comment-thread [comments]="comments"></comment-thread> 
</ion-content>

<ion-footer>
  <ion-toolbar>
    <comment-form></comment-form>
  </ion-toolbar>
</ion-footer>

在我的父组件中,我输入虚拟数据,然后将其传递给子项:

<comment-thread [comments]="comments"></comment-thread>

评论-thread.ts

import {Component, Input} from '@angular/core';

@Component({
    selector: 'comment-thread',
    templateUrl: 'comments-thread.html'
})
export class CommentsThreadComponent {
    @Input() comments: any[];
    constructor () {}
}

评论-thread.html

<ion-item *ngFor="let comment of comments">
  <comment [comment]="comment"></comment>
</ion-item>

comment.component.ts

import {Component, Input} from '@angular/core';
import { Comment } from '../comment.service'

@Component({
    selector: 'comment',
    template: '{{ comment.message }}'
})
export class CommentComponent {
    @Input() comment: any;
}

评论-form.ts

import {Component} from '@angular/core';
import {Comment} from '../comment.service';
import {Validators, FormBuilder, FormGroup } from '@angular/forms';

@Component({
    selector: 'comment-form',
    providers: [
        Comment
    ],
    template: `
      <form [formGroup]="_commentForm" (ngSubmit)="addComment()" (ngModel)="comments">
        <ion-item>
          <ion-input 
            type="text" 
            placeholder="Write a comment"
            formControlName="message"
            [(ngModel)]="newComment"></ion-input>
        </ion-item>
            <button ion-button type="submit" [disabled]="!_commentForm.valid">Submit</button>
      </form>
    `
})
export class CommentForm {
    private _commentForm: FormGroup;

    constructor ( private _formBuilder: FormBuilder, private _CommentApi: Comment) {
        this._commentForm = this._formBuilder.group({
            message: ['', Validators.required],
        })
    }

    addComment() {
        this._CommentApi.addComment({
            "id": "adsfa",
            "date": "1234455543",
            "author": "rockwcl1",
            "message": this._commentForm.value.message
        });
    }

}

我最近才开始尝试弄清楚[(ngModel)]是否是我需要的。

那么,现在发生了什么:

  • 最初查看页面时,我看到包含前两个评论的列表很好
  • 当我通过表单添加评论时,它是push正确{我看到他们使用console.log()
  • 评论列表未更新

我想我只是期待魔术 - 我更新了数据,因此列表会更新。当我推送新项目时,我需要更改以更新列表呢?

[修改:添加新评论时显示console.log的YouTube视频的链接:https://www.youtube.com/watch?v=NxHuDbcwvEE]

2 个答案:

答案 0 :(得分:1)

我已经模拟了您的代码(减去表单,因为您说新消息正在登录到控制台),但它在这里工作正常:Plunker

因此,变更检测工作正常。

供参考,这是Plunker代码。如果问题出在其中,请您发布完整的组件。

@Component({
  selector: 'comment-thread',
  template: `
    <ul>
      <li *ngFor="let comment of comments">
        <comment [comment]="comment"></comment>
      </li>
    </ul>  
  `
})
export class CommentThreadComponent {
  @Input() comments;  
}

@Component({
  selector: 'comment',
  template: '{{ comment.message }}'
})
export class CommentComponent {
  @Input() comment;  
}

@Component({
  selector: 'my-app',
  template: `
    <div>
      <h2>Hello {{name}}</h2>
      <button (click)="addSomeComment()">Add a message</button>
      <comment-thread [comments]="comments"></comment-thread>
    </div>
  `,
})
export class App {
  name:string;
  comments: any;
  constructor(private _commentApi: Comments) {
    this.name = `Angular! v${VERSION.full}`;
    this.comments = this._commentApi.getComments();
  }
  addSomeComment() {
    this._commentApi.addComment({message: 'yet another comment'})
  }
}

ComponentAPI不是单身

问题是由表单组件中的提供程序部分引起的。

@Component({
  selector: 'comment-form',
  // providers: [
  //     Comment
  // ],
  template: `

基本上,由于CommentAPI持有数据,因此您需要将其作为单例。但是,您在EventDiscussionPage以及CommentForm中提供了它,因此Angular会生成两个实例。

诀窍是提供一次比其任何一个客户端组件更高的级别。通常,app.module.ts最好。

答案 1 :(得分:0)

您需要使用 @ angular / core 中的 ChangeDetectorRef 模块。您可以在此处查看相关文档:

  

https://angular.io/api/core/ChangeDetectorRef