带有数组的角度绑定对象从组件到使用 ngModels 进行查看

Posted

技术标签:

【中文标题】带有数组的角度绑定对象从组件到使用 ngModels 进行查看【英文标题】:Angular binding object with array from component to view with ngModels 【发布时间】:2018-02-08 16:12:08 【问题描述】:

我尝试在视图上绑定模型,但在提交表单时出现问题:我没有数组,但有很多属性。

组件:

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

初始对象:

提交后的控制台:

提交后我想要和初始对象一样的东西(更新数据的相同结构),提交前后相同的数据结构

在我看来,我试过这个,但它不起作用:

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

我通过 [ngModel]="answer.text" 在 *ngFor [ngModel]=question.answers[i].text 中进行转换,但我有同样的问题...

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

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

我想在没有响应式表单的情况下这样做,只有模板驱动

演示:

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

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

已解决

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

【问题讨论】:

从您的模板中,为您的Add Question 按钮添加代码 @Faisal 我更新了我的帖子 我不完全确定问题出在哪里,但如果您没有获取数据,则需要为每个输入添加一个独立属性 @mast3rd3mon 提交后我想要与初始对象相同的东西(更新数据的相同结构) 您的意思是要重置数据?或者你想要相同的数据结构? 【参考方案1】:

你可以这样做:-

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

我看到您在 html 模板中使用了[ngModel]。这只会绑定输入以绑定输出,您还需要使用[(ngModel)]。这是使用ngModel 的常规方式。我在您的代码中发现另一个错误,name="answer[i].value"here name is value 应该是常量,您将其作为变量提供,正确的写法是 name="answer[i].value"

【讨论】:

当我用你的修改修改我有很多错误,如果你想试试:stackblitz.com/edit/angular-by7uv1 嗨,我修改了我在答案中所说的代码,它运行良好这是我在 html 中添加的代码。 我无法在此处添加它说的很长的 html 代码。我如何将代码分享给您 你可以在 stackbiltz 上 Fork 我的项目并在你的帖子中分享链接 确定:错误类型错误:无法读取 Object.eval [as updateDirectives] (AppComponent.html:31) at Object.debugUpdateDirectives [as updateDirectives] 处未定义的属性“0”(【参考方案3】:

以下场景无法使用当前的 Angular 模板驱动表单。 Angular 团队 LINK 提出了一个问题。

由于模板驱动的表单使用 ngModel ,因此需要大量返工。 Angular Forms 正朝着反应式方法发展,在近乎的功能中,我没有看到此功能被添加到其中。

请为此formArrayName 使用响应式表单将足以帮助获得所需的结果。

【讨论】:

【参考方案4】:

问题是,无论指定什么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

【讨论】:

【参考方案5】:
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中声明 如何在表单控件中存储对象值数组

【讨论】:

以上是关于带有数组的角度绑定对象从组件到使用 ngModels 进行查看的主要内容,如果未能解决你的问题,请参考以下文章

将变量从商店绑定到角度ngrx中的组件

如何使用 ngModel 在 div 的 innerhtml 属性上实现 2 路数据绑定?

“无法绑定到 'ngModel',因为它不是 'p-calendar' 的已知属性”尝试使用 PrimeNG 组件的错误消息,为啥?

如何为动态添加的新输入行设置 ngModel 角度 4+(mat-table)

*ngFor 如何使用索引将数组中的每个项目绑定到 ngModel

在 textarea 上使用 [(ngModel)] 绑定时如何避免 ExpressionChangedAfterItHasBeenCheckedError