我正在创建一个"邀请成员"用户可以添加任意数量的"成员的形式"到表格立即邀请。我找到了这件作品。
我还有一个动态创建的复选框列表,对应于用户可以关联的团队,因此我需要根据动态列表动态创建这些控件。
我遇到的问题是,我的表单似乎从所有嵌套中变得有点复杂,并且由于这些团队的动态特性,我遇到了一些问题。我遇到的主要问题是错误:
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);
}
有人能否对我失踪的事情有所了解?我觉得我几乎得到了它。
答案 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。我还修改了可见性数组,使事情变得简单。