在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;
}
}
答案 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);
}
}