Angular binding object with array from component to view with ngModels
I tried to bind my model on my view, but I have a problem when I submit my form : I don't have an array, but many property.
component :
export class QuizFormAddQuestionComponent implements OnInit {
public question: Question;
constructor() {
this.question = new Question();
}
ngOnInit() {
this.question.setModel({ question: 'test' });
this.question.setAnswers(3);
}
createQuestion(form) {
console.log(form.value);
}
}
my template :
<hello name="{{ name }}"></hello>
<div class="row">
<div class="col-sm-1"></div>
<div class="col-sm-10">
<form #form="ngForm" (ngSubmit)="createQuestion(form)" class="mt-4">
<div class="form-row">
<div class="form-group col-md-12">
<label for="question" class="col-form-label">Question</label>
<input type="text"
class="form-control"
id="question"
placeholder="Enter your question..."
name="question"
[ngModel]="question.question"
required>
</div>
</div>
<div class="form-group row" *ngFor="let answer of question.answers; let i = index;">
<div class="col-sm-12">
<div class="form-check">
<label class="form-check-label">
<input class="form-check-input"
type="checkbox"
id="answer-value-{{i}}"
[ngModel]="question.answers[i].value"
name="answers[{{i}}].value">
Answer {{ i }}
</label>
</div>
<input type="text"
class="form-control"
id="answer-text-{{i}}"
[ngModel]=question.answers[i].text
name="answers[{{i}}].text">
{{ answer.getManipulateObjet() }}
</div>
</div>
<div class="form-row">
<div class="form-froup col-md-12 text-right">
<button type="submit" class="btn btn-primary">Add question</button>
</div>
</div>
</form>
</div>
</div>
question.ts (model)
import { Answer } from "./answer";
export class Question {
constructor(private question: string = '',
private answers: any[] = [],
private more_informations: string = '',
private difficulty: number = 0,) {
}
setModel(obj) {
Object.assign(this, obj);
}
addAnswer() {
let new_answer = new Answer();
new_answer.setModel({ text: 'test', value: false });
this.answers.push(new_answer);
}
setAnswers(number_answers) {
for (let i = 0; i < number_answers; i++) {
this.addAnswer();
}
console.log(this);
}
}
answer.ts (model)
export class Answer {
constructor(private text: string = '',
private value: boolean = false,) {
}
setModel(obj) {
Object.assign(this, obj);
}
getManipulateObjet() {
return '=== call getManipulateObjet() for example : return more information after manipulating object, count value properties, concat, etc... ===';
}
getCount() {
// ....
}
getInspectMyObject() {
// ...
}
}
initial object :
console after submit :
After the submit I would like the same things as the initial object (same structure with the data updated), the same data structure before and after submit
I tried this on in my view, but it doesn't work :
<div class="form-group row" *ngFor="let answer of question.answers; let i = index;">
<div class="col-sm-12">
<div class="form-check">
<label class="form-check-label">
<input class="form-check-input"
type="checkbox"
id="answer-value-{{i}}"
[ngModel]="answer.value"
name="answer[{{i}}].value">
Answer {{ i }}
</label>
</div>
<input type="text"
class="form-control"
id="answer-text-{{i}}"
[ngModel]=answer.text
name="answer[{{i}}].text">
{{ answer.getManipulateObjet() }}
</div>
</div>
I transform in the *ngFor [ngModel]=question.answers[i].text by [ngModel]="answer.text" , but I have the same problem...
I tried many things from differents posts : Angular 2 form with array of object inputs, Angular 2 - 2 Way Binding with NgModel in NgFor
But always many properties and no array
I would like to do this without reactive form, only template driven
Demo:
https://angular-by7uv1.stackblitz.io/
I would like to use different function from my object 'answer', for example : answer.getInformation(), getCount(), getInspectMyObject() etc.. to iterate on my object only, in my view. This function is provided by my model 'Answer' to have a clean code in my view. I would like use many functions from my model in the *ngFor. If I use the reactive form, I can't use different function from my model because the "link" between my parent object and my childs is broken.
SOLVED
https://fom-by-template-driven.stackblitz.io
The problem is, whatever the input
name specified, it will be considered as just text. Should not reference any Object
or Array
.But with slight modifications, there is a chance to obtain the same data structure with updated data.
All elements are binded in one way, so make it two way binding. So whenever input
value changes, The binded element
value updates.
[(ngModel)]="question.question"
Use template driven form
for validation
<form #form="ngForm" (ngSubmit)="createQuestion()" class="mt-4">
...
<button [disabled]="!form.valid"
Now the values are validated & updated in the variable question
.There is no need to get the value from form, use the updated object question
to create question.
createQuestion() {
console.log(this.question);
}
View the results in worked out App
你可以做这样的事情: -
import {Component, OnInit} from '@angular/core';
import {FormGroup, FormArray, FormControl} from '@angular/forms';
@Component({
selector: 'form-component',
template: `
<form [formGroup]="formGroup">
<div formArrayName="inputs" *ngFor="let control of formArray; let i = index;">
<input placheholder="Name please" formControlName="{{i}}"/>
</div>
</form>
<button (click)="addInput()">Add input</button>
`
})
export class FormComponent implements OnInit{
formGroup: FormGroup;
contructor() {
}
ngOnInit(){
this.formGroup = new FormGroup({
inputs: new FormArray([
new FormControl("Hello"),
new FormControl("World"),
]);
});
}
get formArray() {
return this.formGroup.get('inputs').controls
}
addInput(){
this.formArray.push(new FormControl("New Input"));
}
}
i see that you are using [ngModel]
in you html template. this will only bind the input to bind the output as well you need to use [(ngModel)]
. this is the regular way of using ngModel
. i find one more wrong in your code that name="answer[{{i}}].value"
here name is value should be constant, you are giving it as variable the correct way of writing it is name="{{answer[i].value}}"
上一篇: 直观的理解功能,参考参考文献