Angular 2表单生成器 - 嵌套元素2级深 - 错误:找不到路径控件

时间:2016-12-14 17:22:28

标签: angular angular2-forms

我正在创建一个"邀请成员"用户可以添加任意数量的"成员的形式"到表格立即邀请。我找到了这件作品。

我还有一个动态创建的复选框列表,对应于用户可以关联的团队,因此我需要根据动态列表动态创建这些控件。

我遇到的问题是,我的表单似乎从所有嵌套中变得有点复杂,并且由于这些团队的动态特性,我遇到了一些问题。我遇到的主要问题是错误:

error_handler.js:45 EXCEPTION: Error in ./InviteMembersComponent class InviteMembersComponent - inline template:60:12 caused by: Cannot find control with path: 'members -> teams'

为简洁起见,以下是相关功能部分的代码:

HTML:

<form [formGroup]="inviteMembersForm" novalidate (ngSubmit)="onInviteMembers(inviteMembersForm.value, inviteMembersForm.valid)" class="ui form">

      <ul>
        <li formArrayName="members">
          <div *ngFor="let member of inviteMembersForm.controls.members.controls; let i=index">
            <ul class="members-info"
              [formGroupName]="i">

              <li class="email">
                <h4>Email Address</h4>
                <sm-input [control]="inviteMembersForm.controls.members.controls[i].controls.email" class="left fluid" placeholder="name@domain.com"></sm-input>
                <small [hidden]="inviteMembersForm.controls.members.controls[i].controls.email.valid || (inviteMembersForm.controls.members.controls[i].controls.email.pristine && !submitted)">
                    A valid email is required
                </small>
              </li>

              <li class="first-name">
                <h4>First Name</h4>
                <sm-input
                  [control]="inviteMembersForm.controls.members.controls[i].controls.firstName"
                  class="left fluid"
                  placeholder="Optional">
                </sm-input>
              </li>

              <li class="last-name">
                <h4>Last Name</h4>
                <sm-input
                  [control]="inviteMembersForm.controls.members.controls[i].controls.lastName"
                  class="left fluid"
                  placeholder="Optional">
                </sm-input>
              </li>

              <li class="teams-button">
                <button (click)="togglePeopleTeamsVisible(i)">
                  <span>Teams</span>
                  <i class="fa fa-chevron-down" *ngIf="!memberTeamsVisibility[i].isVisible"></i>
                  <i class="fa fa-chevron-up" *ngIf="memberTeamsVisibility[i].isVisible"></i>
                </button>
              </li>

              <li class="remove-button" *ngIf="(i + 1) > 1">
                <button (click)="removeMember(i)"><img src="/assets/images/icons/close.svg" width="20" /></button>
              </li>
            </ul>
            <div class="teams-block"
            *ngIf="memberTeamsVisibility[i].isVisible"
            formArrayName="teams">
              <ul class="team-list"
                *ngFor="let team of inviteMembersForm.controls.members.controls.teams.controls; let j=index">
                <li [formGroupName]="j">


                </li>
              </ul>
            </div>
          </div>
        </li>
        <li>
          <button class="add-invite" (click)="addMember()">
            <img src="/assets/images/icons/invite-add-blue.svg" width="16" />
            <span>Add another invitation</span>
          </button>
        </li>
        <li><input type="submit" [disabled]="!inviteMembersForm.valid" class="btn" value="Invite {{inviteMembersForm.controls.members.controls.length}} Person" /></li>
      </ul>
    </form>

打字稿:

public inviteMembersForm: FormGroup;
  public memberTeamsVisibility: any = [];

  public teams: any = [
    {
      id: 1,
      title: "Engineering",
      count: 3,
    },
    {
      id:2,
      title: "Sales",
      count: 1
    },
    {
      id:3,
      title: "Marketing",
      count: 2
    }
  ];

  constructor(
    private _fb: FormBuilder,
    private _validators: ValidatorsService
  ) {

    this.createInviteMembersForm();
  }

  ngOnInit() {
  }

  /**
   *  Creation of form for "Invite member"
   */
  createInviteMembersForm() {
    this.inviteMembersForm = this._fb.group({
      members: this._fb.array([this.initMember()])
    });

    // Add a team visibility toggle for the newly added member
    this.addMemberTeamVisibilityToggle();

     // Add the teams
    this.addTeams();

    console.log(this.inviteMembersForm.controls['members']['controls'][0]['controls']['teams']);
  }

  /**
   *  Create a form group for adding an "invite member" form
   */
  initMember() {
    return this._fb.group({
        email: ['', [<any>Validators.required, this._validators.isValidEmail]],
        firstName: ['', []],
        lastName: ['', []],
        teams: this._fb.array([])
    });
  }

  // Add teams to the form
  addTeams() {
    const teamsControl = <FormArray>this.inviteMembersForm.controls['members']['controls'][0]['controls']['teams'];
    this.teams.forEach(team => {
      teamsControl.push(this.addTeam(team.title));
    })
  }


  /**
   *  Adds a team form group to the user
   */
  addTeam(title) {
    return this._fb.group({
        team: [title, []]
    });
  }

  /**
   *  Add an entry for teams visibility anytime a new member is added
   */
  addMemberTeamVisibilityToggle() {
    let membersLength = this.inviteMembersForm.controls['members']['_value'].length;
    for(let i = 0; i < membersLength; i++) {
      this.memberTeamsVisibility.push({ isVisible: false});
    }
  }


  /**
   *  Add a member to the form
   */
  addMember() {
    // add address to the list
    const control = <FormArray>this.inviteMembersForm.controls['members'];
    control.push(this.initMember());
    this.addMemberTeamVisibilityToggle();
  }

  removeMember(i: number) {
    const control = <FormArray>this.inviteMembersForm.controls['members'];
    control.removeAt(i);
    this.memberTeamsVisibility.removeAt(i);
  }

有人能否对我失踪的事情有所了解?我觉得我几乎得到了它。

1 个答案:

答案 0 :(得分:0)

模板中teams的访问者确实有点不正确。

您需要确保设置formGroupName您正在访问的ul,就像在<div [formGroupName]="i"> <div class="teams-block" *ngIf="memberTeamsVisibility[i]" formArrayName="teams"> <ul class="team-list" *ngFor="let team of inviteMembersForm.controls.members.controls[i].controls.teams.controls; let j=index"> <li [formGroupName]="j"> </li> </ul> <pre>{{inviteMembersForm.controls.members.controls[i].value | json}}</pre> </div> </div> 以上一样,并确保选择正确的控制路径:

addTeam(title) {
  let control = {};
  control[title] = new FormControl('');
  return this._fb.group(control);
}

进一步采取措施并完成绑定将需要额外的一些技巧,以使事情更容易,更自动化。团队组实例化将更改为:

return args ? (args.indexOf('single') > -1 ? key : keys) : keys;

这样我们就可以通过参数来访问模板中的对象键(带keys pipe),当我们知道我们只有一个键并希望直接变换时<div [formGroupName]="i"> <div class="teams-block" *ngIf="memberTeamsVisibility[i]" formArrayName="teams"> <ul class="team-list" *ngFor="let team of inviteMembersForm.controls.members.controls[i].controls.teams.controls; let j=index"> {{team.value | keys: 'single'}} <span *ngFor="let control of team.controls | keys"> <input type="checkbox" [formControl]="control"/> </span> </ul> </div> </div> 这意味着我们现在可以将模板编写为:

{{1}}

这里有一个你可以玩的Plunker。我还修改了可见性数组,使事情变得简单。