web-dev-qa-db-ja.com

AngularオブジェクトをコンポーネントからngModelsで表示する配列にバインドする

ビューでモデルをバインドしようとしましたが、フォームを送信するときに問題が発生します。配列はありませんが、多くのプロパティがあります。

コンポーネント:

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

送信後、最初のオブジェクトと同じもの(データが更新された同じ構造)、送信前後の同じデータ構造が欲しい

私の見解ではこれを試してみましたが、機能しません:

<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] .textby[ngModel] =に変換します"answer.text"、しかし私は同じ問題を抱えています...

私はさまざまな投稿から多くのことを試しました: オブジェクト入力の配列を持つAngular 2フォームAngular 2-NgForのNgModelを使用した2ウェイバインディング

しかし、常に多くのプロパティがあり、配列はありません

リアクティブフォームなしでこれを実行したいのですが、テンプレート駆動型のみです

デモ:

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

オブジェクト「answer」とは異なる関数を使用したいと思います。たとえば、answer.getInformation()、getCount()、getInspectMyObject()などを使用して、ビュー内でオブジェクトのみを反復処理します。この関数は、私のモデル「Answer」によって提供され、私のビューにクリーンなコードが含まれています。 * ngForでモデルの多くの関数を使用したいと思います。リアクティブフォームを使用すると、親オブジェクトと子の間の「リンク」が壊れているため、モデルとは異なる関数を使用できません。

解決済み

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

7

問題は、指定されたinput名が何であれ、それが単なるテキストと見なされることです。 ObjectまたはArrayを参照しないでください。ただし、わずかな変更を加えるだけで、更新されたデータで同じデータ構造を取得できる可能性があります。

すべての要素は一方向でバインドされるため、双方向でバインドします。したがって、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);
    }

結果を表示するアプリ

3
Rajez

次のシナリオは現在のAngularテンプレート駆動型フォームでは不可能です。 Angularチームに問題が発生しました [〜#〜] link [〜#〜] =。

テンプレート駆動型フォームはngModelを使用するため、多くの手直しが必要です。 Angularフォームはリアクティブアプローチに移行しており、近くの機能では、この機能が追加されているのがわかりません。

このformArrayNameにはリアクティブフォームを使用してください。目的の結果を得るには、十分です。

0
Rahul Singh

hTMLテンプレートで_[ngModel]_を使用しているようです。これは、入力をバインドして出力をバインドするだけであり、[(ngModel)]を使用する必要があります。これは、ngModelを使用する通常の方法です。 _name="answer[{{i}}].value"_ここで名前は定数でなければならないというあなたのコードのもう1つの間違いを見つけました、あなたはそれを変数として与えていますそれを書く正しい方法は_name="{{answer[i].value}}"_です

enter image description here

0
Sunil Kumar

あなたはこのようなことをすることができます:-

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

}
0
JSingh
academicYearTerms: [{
    term_name: {
        type: String,
        default: " "
    },
    term_end: {
        type: Date,
    },
    term_start: {
        type: Date,
    },
}]

ノードjsで宣言する

adminpageform = new FormGroup({
    start_date: new FormControl(''),
    end_date: new FormControl(''),
    acadyr_shortcode: new FormControl(''),
    no_terms: new FormControl(''),
    term_name: new FormControl(''),
    term_end: new FormControl(''),
    term_start: new FormControl(''),
    TermsId: new FormControl('')
});

フォームコントロールのオブジェクト値の配列に格納する方法をtsで宣言します

0
Arun kumar