ngIf

时间:2018-10-07 21:45:25

标签: angular ngif

https://github.com/jimshowalter/vocabutron/blob/master/src/app/settings/settings.component.html中,应用程序仅显示设置按钮启动。单击按钮,该按钮消失,由设置编辑器代替。编辑设置并提交,您可以看到它被推送到设置服务。提交还会使该组件消失,并带回设置按钮。但是第二次单击设置按钮,则该设置丢失。并且控制台日志完全不显示设置组件中的任何活动。它似乎已经死了。但是,为设置添加值并提交后,该组件仍然存在(如控制台所示)。

为什么不重新显示组件,将现有数据填充到编辑器中?

import { Component, OnInit, isDevMode } from "@angular/core";
import { SettingsService } from "../settings.service";
import { Settings } from "../settings";

@Component({
  selector: "app-settings",
  templateUrl: "./settings.component.html",
  styleUrls: ["./settings.component.css"]
})
export class SettingsComponent implements OnInit {
  model: Settings = null;
  display: boolean = false;

  constructor(private settingsService: SettingsService) {
    if (isDevMode) {
      console.log("SettingsComponent.constructed");
    }
  }

  private updateSettings() {
    if (isDevMode) {
      console.log("SettingsComponent.updateSettings");
    }
    this.model = this.settingsService.get();
  }

  ngOnInit() {
    if (isDevMode) {
      console.log("SettingsComponent.ngOnInit");
    }
    this.settingsService.changedMessage.subscribe(changed =>
      this.updateSettings()
    );
  }

  onSubmit(): void {
    let result = this.settingsService.put(this.model);
    if (isDevMode) {
      console.log("SettingsComponent.onSubmit: " + JSON.stringify(result));
    }
    this.display = false;
  }
}

<div *ngIf=!display class="container">
  <button type="button" class="btn btn-success" (click)="display=true">Settings</button>
</div>
<div *ngIf=display class="container">
  <h2>Settings</h2>
  <form (ngSubmit)="onSubmit(); settingsForm.reset()" #settingsForm="ngForm">
    <div class="form-group">
      <input type="number" class="form-control" id="settings" [(ngModel)]="model.maxWords" required pattern="([1-9]+[0-9]*)+"
        name="settings" #settingsModel="ngModel">
    </div>
    <div [hidden]="settingsModel.valid || settingsModel.pristine" class="alert alert-danger">
      Max words is required and must be a number from 1-N.
    </div>
    <button type="submit" class="btn btn-success" [disabled]="!settingsForm.form.valid">Submit</button>
  </form>
</div>

export class Settings {
  maxWords: number = 3;
}

import { Injectable, isDevMode } from "@angular/core";
import { BehaviorSubject } from "rxjs";
import { Settings } from "./settings";

@Injectable({
  providedIn: "root"
})
export class SettingsService {
  changedMessageSource = new BehaviorSubject("changed");
  changedMessage = this.changedMessageSource.asObservable();

  private settings: Settings = new Settings();

  constructor() {
    if (isDevMode) {
      console.log("SettingsService constructed");
    }
  }

  get(): Settings {
    if (isDevMode) {
      console.log("SettingsService.get");
    }
    return this.settings;
  }

  changed() {
    if (isDevMode) {
      console.log("SettingsService.changed");
    }
    this.changedMessageSource.next("changed");
  }

  put(settings: Settings): Settings {
    this.settings = settings;
    this.changed();
    if (isDevMode) {
      console.log("SettingsService.put: " + JSON.stringify(this.settings));
    }
    return this.settings;
  }
}

1 个答案:

答案 0 :(得分:0)

发生这种情况的原因是您通过在表单提交处理程序中调用reset()来重置表单,但是由于仅隐藏表单并使用* ngIf重新显示该表单,因此没有阶段模型得到更新。不会触发该主题,因此不会调用更新。只需删除重置即可修复。

  <form (ngSubmit)="onSubmit();" #settingsForm="ngForm">

这种编码风格几乎没有问题,例如,如上所示的复杂推理和性能变化检测,但我认为这些概念还有待解决。目前,BehaviorSubject可以直接向对象发出更改。直接订阅此功能即可一步一步获得新设置。

ngOnInit() {
   this.settingsService.settings$.subscribe(settings =>
     this.model = settings;
  );
}

export class SettingsService {
  private settings: Settings = new Settings();

  private settingsSource = new BehaviorSubject(this.settings);
  settings$ = this.settingsSource.asObservable();

  ...

  changed() {
    this.settingsSubject.next(this.settings);
   }
}