当您单击添加按钮时,ngFor不显示数据,也无法添加数据

时间:2019-01-13 09:45:19

标签: angular ngfor

我想在列表中显示服务中的数据,并在我打开网站时立即加载数据,当您单击“添加”按钮时,它将在列表中显示添加的数据。我正在使用角度7。

就目前而言,当我单击添加按钮时,它显示的是movies.service.ts中的数据,这与我预期的不一样,我希望打开网站后立即显示该数据,当您单击添加按钮时,它会添加我输入的数据。

感谢您的帮助。

// from app.component.html

<app-movie-lists></app-movie-lists>    

// from appModule

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import {FormsModule} from '@angular/forms';
import { AppComponent } from './app.component';
import { MoviesComponent } from './movies/movies.component';
import { MovieListsComponent } from './movie-lists/movie-lists.component';
import { MoviesService } from './movies.service';


@NgModule({
  declarations: [
    AppComponent,
    MoviesComponent,
    MovieListsComponent
  ],
  imports: [
    BrowserModule,
    FormsModule
  ],
  providers: [MoviesService],
  bootstrap: [AppComponent]
})
export class AppModule { }



// from movies.service.ts  , this is the data I'd like to immediately when i open the site.

import { Movies } from './app.model';
import { Subject } from 'rxjs';



export class MoviesService {
moviesChanged = new Subject<Movies[]>();

    movies: Movies[] = [
      {
            title: 'Mr & Mrs Smith',
            actors: ['Brad Pitt', 'Angelina Jolie'],
            releasedDate: '2010-03-18'
        },
        {
            title: 'Titanic',
            actors: ['Leonardo deCaprio', 'Cate Winslet'],
            releasedDate: '2008-03-20'
        }
    ];


    getMovies() {
        this.movies.slice();
    }

    addMovie(movie: Movies) {
        this.movies.push(movie);
        this.moviesChanged.next(this.movies.slice());
    }
}


// from app.model.ts

export class Movies {
    title: string;
    actors: string[];
    releasedDate: string;
}

// from movies.component.html, this is the form where I would like to input data and when you click the button add it will show the data in a lists which added from the existing preloaded data.

  <div class="row">
    <div class="col-xs-12">
      <form (ngSubmit)="onSubmit(f)" #f= "ngForm">
        <div class="row">
            <div class="col-xs-12">
        <div class="form-group">
          <label for="title">Title</label>
          <input type="text" class="form-control" id="title"
          ngModel
          name="title">
        </div>
            </div>
      </div>
      <div class="row">
        <div class="col-xs-12">
          <div class="form-group" >
            <label for="actors">Actors</label>
            <input type="text" class="form-control" id="actors"
            ngModel
            name="actors">
          </div>
        </div>
        </div>
        <div class="row">
            <div class="col-xs-12">
            <div class="form-group">
              <label for="releasedDate">Released Date</label>
              <input type="text" class="form-control" id="releasedDate"
              ngModel
              name="releasedDate">
            </div>
            </div>
          </div>
          <button class= "btn btn-primary" type="submit">Add</button>
      </form>                   
    </div>
  </div>


// from movies.component.ts

import { Component, OnInit, ViewChild, Input } from '@angular/core';
import { Movies } from '../app.model';
import { NgForm } from '@angular/forms';
import { MoviesService } from '../movies.service';

@Component({
  selector: 'app-movies',
  templateUrl: './movies.component.html',
  styleUrls: ['./movies.component.css']
})
export class MoviesComponent implements OnInit {

  @ViewChild('f') formData: NgForm;
  constructor(private moviesService: MoviesService) { }

  ngOnInit() {
  }

  onSubmit(form: NgForm) {
    const value = form.value;
    const newMovie = new Movies(value.title, value.actors, value.releasedDate);  // having problem in here,  it says expected 0 argument but got 3
    this.moviesService.addMovie(newMovie);
    }

  }    


// from movie-lists.component.html    

<div class="container">
  <div class="col-xs-12">
      <div class="row">
          <div class="col-xs-6">
              <app-movies></app-movies >
          </div>
        </div> 
        <div class="row">
            <div class="col-xs-6">
              <ul class="list-group" *ngFor= "let movie of movies">
                <li class="list-group-item"  >
                 {{movie.title}}
                </li>
                <li class="list-group-item" >
                    {{movie.actors}}
                   </li>
                   <li class="list-group-item" >
                      {{movie.releasedDate}}
                     </li>
              </ul>
            </div>
          </div>         
  </div>
</div>


// from movie-lists.component.ts


import { Component, OnInit } from '@angular/core';
import { Movies } from '../app.model';
import { MoviesService } from '../movies.service';

@Component({
  selector: 'app-movie-lists',
  templateUrl: './movie-lists.component.html',
  styleUrls: ['./movie-lists.component.css']
})
export class MovieListsComponent implements OnInit {
movies: Movies[];
  constructor(private moviesService: MoviesService) { }

  ngOnInit() {
     this.moviesService.getMovies();
    this.moviesService.moviesChanged.subscribe(
      (movies: Movies[]) => {
    this.movies = movies;
      }
    );
  }

}

2 个答案:

答案 0 :(得分:0)

您的代码中有些开销。首先,尝试更改

moviesChanged = new Subject<Movies[]>();

moviesChanged = new BehaviorSubject<Movies[]>(this.movies);

因为它将为订购该组件的组件提供初始的“电影”值。

此外,代替:

ngOnInit() {
         this.moviesService.getMovies();
        this.moviesService.moviesChanged.subscribe(
          (movies: Movies[]) => {
        this.movies = movies;
          }
        );
      }

您可以简单地在模板中使用“异步”管道:

<ul class="list-group" *ngFor= "let movie of moviesService.moviesChanged | async">

这样,您不必担心组件被销毁时取消订阅。

答案 1 :(得分:0)

有多种方法可以解决此问题(代码未经测试,可能包含一些编译错误):

  1. moviesChanged = new Subject<Movies[]>()替换为moviesChanged = new BehaviorSubject<Movies[]>(this.movies); 当调用subscribe时,BehaviorSubject直接返回实际值或默认值(构造函数参数)。

More about different Subject

  1. 另一种方法:更改方法getMovies()
getMovies() : Movie[] {
    return this.movies.slice();
}

当您调用它时: this.movies = this.moviesService.getMovies();初始化电影。