Angular binding object with array from component to view with ngModels

时间:2017-08-30 20:16:53

标签: angular angular2-forms angular4-forms

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 :

>>> d2 = pd.DataFrame(dict(A=np.int32([0]), B=np.int64([0])))
>>> d2.values[:, 1] = 3
>>> print(d2)
   A  B
0  0  0

my template :

>>> d2 = pd.DataFrame(dict(A=np.int32([0]), B=np.int32([0])))
>>> d2.values[:, 1] = 3
>>> print(d2)
   A  B
0  0  3

question.ts (model)

>>> np.shares_memory(d1.values, d1.A.values)
True

>>> np.shares_memory(d2.values, d2.A.values)
False

answer.ts (model)

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

}

initial object :

enter image description here

console after submit :

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

I tried this on in my view, but it doesn't work :

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

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

5 个答案:

答案 0 :(得分:3)

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

所有元素都以一种方式绑定,因此请进行双向绑定。因此,每当input值更改时,绑定的element值都会更新。

 [(ngModel)]="question.question"

使用template driven form进行验证

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

现在价值得到验证&amp;在变量question中更新。无需从表单中获取值,使用更新的对象question来创建问题。

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

View the results in worked out App

答案 1 :(得分: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"));
  }

}

答案 2 :(得分:0)

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

enter image description here

答案 3 :(得分:0)

以下方案使用当前的Angular Template驱动表单 。 向Angular团队LINK提出了一个问题。

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

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

答案 4 :(得分:0)

$

在节点js中声明

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

在ts中声明 如何在表单控件的对象值数组中存储