Angular 2 - 具有动态对象/属性的ngModel

时间:2016-11-22 03:57:35

标签: angular typescript angular2-ngmodel

在我的TS文件中,我在selectedValsObj对象上动态创建属性,如下所示:

private selectValsObj: any = {};

setSelectedValsObj(sectionsArr) {
  sectionsArr.forEach(section => {
    section.questions.forEach(questionObj => {
      if (questionObj.type === 'drop-down') {
        this.selectValsObj[questionObj.questionId] = { selected: questionObj.answerDetails[0] };
      }
    })
  });
}

在我的HTML中,我希望将输入上的[ngModel]绑定到selectValsObj对象上的属性。我试过这个,但没有运气:

<div *ngFor="let question of section.questions">
    <div class="drop-down-question" *ngIf="question?.type === 'drop-down'">
        <select class="q-select"
                [(ngModel)]="selectValsObj[questionId].selected" // <== doesnt work either**
                // [(ngModel)]="selectValsObj[{{ questionId }}].selected" // <== doesnt work**
                name="answerForQuestion{{ question?.questionId }}">
            <option *ngFor="let answer of question?.answerDetails"
                [ngValue]="answer">
                    {{ answer?.value }}
            </option>
        </select>
    </div>
</div>

如何将HTML中的ngModel设置为TS文件中动态创建的属性?

4 个答案:

答案 0 :(得分:3)

我试图复制这种情况但是在代码中,你发布的内容似乎是多个问题。

  1. 属性selectValsObj声明为private,但您尝试在模板中使用它
  2. 您尝试迭代section.questions的模板中的
  3. 但我看不到它在其他任何地方定义,而是在每个本地范围的setSelectedValsObj方法中定义
  4. 由于缺少类型定义,您可能错误地使用了数据
  5. 这是我理解的代码并添加了typedef

    interface QuestionModel {
      type: string;
      questionId: string;
      answerDetails: string[];
    }
    
    const MOCK_DATA = [
      {
        questions: [{
          type: 'drop-down',
          questionId: '42',
          answerDetails: ['wololo'],
        }],
      },
    ];
    
    
    @Component(...)
    export class ProductsComponent {
      selectValsObj: { [key: string]: { selected: string } } = {};
    
      constructor() {
        this.setSelectedValsObj(MOCK_DATA);
      }
    
      setSelectedValsObj(sectionsArr: { questions: QuestionModel[] }[]) {
        sectionsArr.forEach(section => {
          section.questions.forEach(questionObj => {
            if (questionObj.type === 'drop-down') {
              this.selectValsObj[questionObj.questionId] = {selected: questionObj.answerDetails[0]};
            }
          });
        });
      }
    }
    

    在检查类型定义是否与您最初的预期相符(并正确使用它)之后,您将防止出现大量错误。

    此外,请考虑使用更多声明性方法,mapfilter您的数据,而不是在方法中使用forEach

答案 1 :(得分:1)

对于HTML代码中的以下行:

[(ngModel)]="selectValsObj[questionId].selected"

如果您没有将questionId定义为在ts文件中的任何位置具有值的变量,则可能是问题所在。

如果您希望获得正在循环的questionId列表中每个question的{​​{1}},可以尝试按以下方式进行操作:

section.questions

我做了一个简单的例子,你可以找到here(在[(ngModel)]="selectValsObj[question.questionId].selected" 中)有不同的工作案例。我希望它可以提供帮助。

答案 2 :(得分:1)

(click)="toggle(address.id)"
  *ngIf="action[address.id]"

在ts文件中:

action: any = {};

在切换方法中

this.action[addressId] = !this.action[addressId];

答案 3 :(得分:0)

  • 目前还不是很清楚你想要达到的目标。
  • 我认为你 正在尝试动态构建一个包含问题和答案的页面 组合框,如果类型为&#39; 下拉列表&#39;。
  • 你也在努力 捕获所选答案。

如果是这样......下面的代码片段可以提供帮助。

import { Component, OnInit } from '@angular/core';

interface Question {
  questionStr: string;
  questionId: string;
  type: string;
  answers: Array<string>;
  selectedAnswer: string;
}

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  title = 'app';

  selectValsArr: Array<Question> = [];

  ngOnInit() {
    this.setSelectedValsObj([
      {
         questionStr : 'Question1',
         questionId: 'Q01',
         type: 'drop-down',
         answers: ['Q1Ans1', 'Q1Ans2', 'Q1Ans3'],
         selectedAnswer: null
      },
      {
        questionStr: 'Question2',
        questionId: 'Q02',
        type: 'drop-down',
        answers: ['Q2Ans1', 'Q2Ans2', 'Q2Ans3'],
        selectedAnswer: null
      },
    ]);
  }


  setSelectedValsObj(sectionsArr: Array<Question>) {
    sectionsArr.forEach(section => {
      if (section.type === 'drop-down') {
        this.selectValsArr.push(section);
        }
    });
  }
}

HTML

<div *ngFor="let question of selectValsArr">
  <h3>{{question.questionStr}}</h3>
  <div class="drop-down-question">
    <select [(ngModel)]="question.selectedAnswer">
      <option value="">Select an Answer</option>
      <option *ngFor="let ans of question.answers" [ngValue]="ans"> {{ans}}</option>
    </select>
  </div>
</div>

<br>
<h2>Selected Answer</h2>

<div *ngFor="let question of selectValsArr">
    <span>{{question.questionStr}}</span>
    <span>&nbsp; &nbsp; - &nbsp; {{question.selectedAnswer}}</span>
</div>