首页 文章

角度绑定对象,使用ngModels从组件到视图的数组

提问于
浏览
7

我试图在我的视图上绑定我的模型,但是当我提交表单时我遇到了问题:我没有数组,但有很多属性 .

零件 :

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);
    }

}

我的模板:

<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(型号)

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(型号)

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() {
      // ...
    }
}

初始对象:

enter image description here

提交后的控制台:

enter image description here

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

我在我的视图中试过这个,但它不起作用:

<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>

我转换为* ngFor [ngModel]=question.answers[i].text[ngModel]="answer.text" ,但我有同样的问题...

我从不同的帖子尝试了很多东西:Angular 2 form with array of object inputsAngular 2 - 2 Way Binding with NgModel in NgFor

但总是很多属性,没有数组

I would like to do this without reactive form, only template driven

演示:

https://angular-by7uv1.stackblitz.io/

我想在我的对象'answer'中使用不同的函数,例如:answer.getInformation(),getCount(),getInspectMyObject()等...在我的视图中仅迭代我的对象 . 这个功能由我的模型'Answer'提供,在我的视图中有一个干净的代码 . 我想在* ngFor中使用我的模型中的许多函数 . 如果我使用反应形式,我不能使用我的模型中的不同功能,因为我的父对象和我的孩子之间的“链接”被破坏了 .

已解决

https://fom-by-template-driven.stackblitz.io

4 回答

  • 0

    问题是,无论 input 名称指定什么,它都将被视为文本 . 不应该引用任何 ObjectArray . 但稍作修改,有可能获得具有更新数据的相同数据结构 .

    所有元素都以一种方式绑定,因此请将其双向绑定 . 因此,只要 input 值发生更改,绑定的 element 值就会更新 .

    [(ngModel)]="question.question"
    

    使用 template driven form 进行验证

    <form #form="ngForm" (ngSubmit)="createQuestion()" class="mt-4">
    ...
    <button [disabled]="!form.valid"
    

    现在,在变量 question 中验证和更新值 . 无需从表单获取值,使用更新的对象 question 来创建问题 .

    createQuestion() {
            console.log(this.question);
        }
    

    View the results in worked out App

  • 0

    你可以这样做: -

    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"));
      }
    
    }
    
  • 3

    我看到你在你的html模板中使用了 [ngModel] . 这只会绑定输入以绑定输出,您需要使用 [(ngModel)] . 这是使用 ngModel 的常规方式 . 我在你的代码中发现了一个错误, name="answer[{{i}}].value" 这里的名称值应该是常量,你给它作为变量的正确写法是 name="{{answer[i].value}}"

    enter image description here

  • 0

    以下方案是 not possible using the current Angular Template driven form . 向Angular Team提出了一个问题LINK .

    由于模板驱动表单使用ngModel,因此需要大量返工 . Angular Forms正朝着被动方式发展,在近距离特征中我没有看到这个特征被添加到它 .

    请使用此 formArrayName 的反应表单足以帮助您获得所需的结果 .

相关问题