Обновлено на основании ответа @Alexander Leonov. Тем не менее, все еще возникают проблемы.
У меня есть форма, которая заполняется при нажатии на список из другого компонента.
Форма, которая заполняется с помощью ngmodel
пустого объекта, который заполняется методом currentTile
в form.ts. Однако, мне не нравится моя структура данных.
В методе currentTile
с использованием form.reset(t)
поля title
and description
заполняются, а фрагменты - нет.
Как видите, с текущей структурой (структура A) фрагменты находятся в объекте, назначенном свойству code
:
tile: Tile = {
id: '',
title: '',
description: '',
code: {snippetA: '', snippetB: '', snippetC: ''},
isStockTile: null
};
С этой структурой, если я использую form.reset(t.code)
, то форма будет сохранять значения фрагмента, но, конечно, значения title
и description
не сохраняются.
Если я выровняю свою структуру данных как (Структура B):
tile: Tile = {
id: '',
title: '',
description: '',
snippetA: '',
snippetB: '',
snippetC: '',
isStockTile: null
};
И используйте form.reset(t)
, после чего заполняются все поля в форме (также изменяя модель Tile
и, соответственно, обновляя назначения ngmodel
в форме). Однако мне не нужно менять структуру данных.
Вот как все настроено в структуре А.
Компонент листинга:
@Component({
selector: 'app-available-tiles',
templateUrl: './available-tiles.component.html',
styleUrls: ['./available-tiles.component.css']
})
export class AvailableTilesComponent implements OnInit {
title = 'Available Tiles';
tiles: Tile[];
isEditing: Boolean = false;
constructor(private tileService: TileService, private router: Router) { }
ngOnInit() {}
editTile(t: Tile) {
this.tileService.tileSelected$.next(t);
this.tileService.isNewTile$.next(false);
}
}
Вид списка:
<ul>
<li *ngFor="let tile of tiles">
<button *ngIf="isEditing && !tile.isStockTile" class="btn btn-info" (click) = "editTile(tile)">[...] {{ tile.title }}
</button>
</li>
</ul>
Компонент формы:
@Component({
selector: 'app-tile-editor',
templateUrl: './tile-editor.component.html',
styleUrls: ['./tile-editor.component.css']
})
export class TileEditorComponent implements OnInit {
title = 'Tile Editor';
showForm: boolean;
@ViewChild ('theForm') form: any;
// The object to hold info to and from the form.
tile = {
id: '',
title: '',
description: '',
code: {snippetA: '', snippetB: '', snippetC: '' },
isStockTile: null
};
constructor(private tileService: TileService, private router: Router) { }
ngOnInit() {
this.tileService.tileSelected$.subscribe(x => this.currentTile(x));
}
currentTile (t: Tile) {
console.log('currentTile: ', t);
this.showForm = true;
this.isNewTile = false;
// Need to reset form so dirty state can be reset.
// Otherwise if a tile is being edited and another tile is loaded into the form prior to Update or Cancel,
// the dirty state will still be applied.
this.form.reset(t);
}
Форма просмотра:
<form #theForm="ngForm">
<label><input [(ngModel)]="tile.title" placeholder="Title" name="title" required #title="ngModel"></label>
<label><input [(ngModel)]="tile.description" placeholder="Description" name="description" required #desc="ngModel"></label>
<label><input [(ngModel)]="tile.code.snippetA" placeholder="Snippet A" name="snippetA" required #snipA="ngModel"></label>
<label><input [(ngModel)]="tile.code.snippetB" placeholder="Snippet B (optional)" name="snippetB"></label>
<label><input [(ngModel)]="tile.code.snippetC" placeholder="Snippet C (optional)" name="snippetC"></label>
<button [disabled]="theForm.form.invalid || !title.dirty && !desc.dirty && !snipA.dirty" type="submit" (click)="updateTile()">Update</button>
</form>