使用反应形式的Angular Firebase编辑对象

时间:2018-11-23 00:45:27

标签: angular typescript firebase firebase-realtime-database

我正在尝试使用反应式表单方法创建此编辑表单。我正在尝试使用FormControl绑定对象的值,但是我无法获得真实的值。我只会得到空值。

在我的服务上,我有一个将返回特定对象的方法,在我的编辑组件上,我初始化了调用服务方法(getSpecificNews)并传递ID的对象。但这不起作用。

这是我的第一个Angular和Firebase项目。有人可以帮忙吗?

news.service.ts

import { map } from 'rxjs/operators';
import { AngularFireDatabase, AngularFireList } from '@angular/fire/database';
import { News } from './news.model';
import { Injectable } from '@angular/core';

@Injectable()
export class NewsService {
    news: AngularFireList<News[]>;
    constructor(private db: AngularFireDatabase) {
    }
    getNews() {
        this.news = this.db.list('news');
        return this.news.valueChanges();
    }

    getSingleNews(id: string) {
        return this.db.object('news/' + id);
    }

    updateNews(news: News) {
        return this.db.database.ref().update(news);
    }

    deleteItem(id: string) {
        this.getSingleNews(id).remove();
    }
}

edit.component.ts

import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';
import { NewsService } from '../news.service';
import { News } from '../news.model';
import { AngularFireDatabase } from '@angular/fire/database';
import { Router, ActivatedRoute, Params } from '@angular/router';

@Component({
  selector: 'app-news-edit',
  templateUrl: './edit.component.html',
  styleUrls: ['./edit.component.css']
})
export class NewsEditComponent implements OnInit {
  @ViewChild('closeBtn') closeBtn: ElementRef;
  editMode = false;
  id;
  news: any;
  newsForm: FormGroup;
  constructor(private newsService: NewsService, private db: AngularFireDatabase, private router: Router, private route: ActivatedRoute) { }

  ngOnInit() {
    this.getRouteID();
    this.news = this.newsService.getSingleNews(this.id).snapshotChanges().subscribe(
      action => {
        this.news = action.payload.val();
      }
    );
    console.log(this.news.title);
    this.initForm();
  }

  private initForm() {
    let theTitle = '';
    let theSubtitle = '';
    let theArticle = '';
    let thePicture = '';

    if (this.editMode) {
      theTitle = this.news.title;
      theSubtitle = this.news.subtitle;
      theArticle = this.news.article;
      thePicture = this.news.picture;
    }

    this.newsForm = new FormGroup({
      'title': new FormControl(theTitle),
      'subtitle': new FormControl(theSubtitle),
      'article': new FormControl(theArticle),
      'picture': new FormControl(thePicture)
    });
  }

  getRouteID() {
    this.route.params.subscribe(
      (param: Params) => {
        this.id = param['id'];
        this.editMode = param['id'] != null;
      }
    );
  }

  onCreateNews() {
    const id = '';
    const title = this.newsForm.value.title;
    const subtitle = this.newsForm.value.subtitle;
    const article = this.newsForm.value.article;
    const picture = this.newsForm.value.picture;

    if (this.editMode) {
      const iD = this.id;
      this.newsService.getSingleNews(this.id).update({title, subtitle, article, picture})
        .then(() => console.log(id, title, subtitle, picture, article))
        .catch((e) => console.log(e));
    } else {
      console.log('entou no else do create news ');
      const newNew = new News(id, title, subtitle, picture, article);
      this.db.database.ref('news/' + newNew.getID()).set(newNew,
        (e) => {
          if (e) {
            console.log(e);
          } else {
            console.log('Data saved');
          }
        });
    }
    this.newsForm.reset();
    this.router.navigate(['/news']);
    this.closeModal();
  }

  closeModal() {
    this.closeBtn.nativeElement.click();
  }

}

edit.component.html

<div class="modal-dialog modal-dialog-centered" role="document">
  <form (ngSubmit)="onCreateNews()" [formGroup]="newsForm">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="exampleModalCenterTitle" *ngIf="!editMode">Adicionar Noticia</h5>
        <h5 class="modal-title" id="exampleModalCenterTitle" *ngIf="editMode">Editar Noticia</h5>
        <button type="button" class="close" data-dismiss="modal" #closeBtn aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body">
        <div class="container">

          <div class="row">
            <div class="col form-group">
              <label for="newsTitle">Titulo</label>
              <input type="text" class="form-control" name="title" id="title" formControlName="title">
              <p>Text: {{ news.title }}</p>
            </div>
          </div>

          <div class="row">
              <div class="col form-group">
                <label for="subtitle">Sub Titulo</label>
                <input type="text" class="form-control" name="subtitle" id="subtitle" formControlName="subtitle">
              </div>
            </div>

          <div class="row">
            <div class="col form-group">
              <label for="article">Noticia</label>
              <textarea name="article" id="article" cols="30" rows="10" class="form-control" formControlName="article"></textarea>
            </div>
          </div>

          <div class="row">
            <div class="col form-group">
              <label for="picture">Picture</label>
              <input type="text" class="form-control" name="picture" id="picture" formControlName="picture">
            </div>
          </div>

        </div>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
        <button type="submit" class="btn orange-btn" *ngIf="editMode">Salvar Mudancas</button>
        <button type="submit" class="btn orange-btn" *ngIf="!editMode">Adicionar Noticia</button>
      </div>
    </div>
  </form>
</div>

news.model.ts

export class News {
    private id: string;
    private title: string;
    private subtitle: string;
    private picture: string;
    private article: string;

    constructor(id: string, title: string, subtitle: string, picture: string, article: string) {
        this.id = this.setID();
        this.title = this.setTitle(title);
        this.subtitle = this.setSubtitle(subtitle);
        this.picture = this.setPicture(picture);
        this.article = this.setArticle(article);
    }

    private setID() {
        function s4() {
            return Math.floor((1 + Math.random()) * 0x10000)
                .toString(16)
                .substring(1);
        }
        return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
    }

    getID() {
        return this.id;
    }

    setTitle(title: string) {
        return this.title = title;
    }

    getTitle() {
        return this.title;
    }

    setSubtitle(sub: string) {
        return this.subtitle = sub;
    }

    getSubtitle() {
        return this.subtitle;
    }

    setPicture(pic: string) {
        return this.picture = pic;
    }

    getPicture() {
        return this.picture;
    }

    setArticle(art: string) {
        return this.article = art;
    }

    getArticle() {
        return this.article;
    }
}

1 个答案:

答案 0 :(得分:0)

这里:

ngOnInit() {
   this.getRouteID(); // <- it is sync method
   this.news = this.newsService.getSingleNews(this.id) // <- so you cannot know this.id
   ...
}

我认为应该是:

public singleNews = null;
ngOnInit() {
   this.newsForm = new FormGroup({
      'title': new FormControl([]),
      'subtitle': new FormControl([]),
      'article': new FormControl([]),
      'picture': new FormControl([])
   });
   this.init();
}
init() {
    this.route.params.subscribe(
      (param: Params) => {
      this.id = param['id'];
      this.editMode = !!this.id;
      this.news = this.newsService.getSingleNews(this.id).snapshotChanges().subscribe(
          action => {
          this.singleNews = action.payload.val();
          this.newsForm.patchValue(this.singleNews);
      });
    });
}

我希望这会有所帮助。