Angular 6:在 *ngFor 中的 formArray 上使用 ngx-pagination 不会更改视图中的控件

Posted

技术标签:

【中文标题】Angular 6:在 *ngFor 中的 formArray 上使用 ngx-pagination 不会更改视图中的控件【英文标题】:Angular 6: Use ngx-pagination on formArray in *ngFor does not change controls in view 【发布时间】:2019-09-09 04:23:35 【问题描述】:

我创建了一个 Angular 6 项目,我在其中获取了一个嵌套的公司对象,该对象包含多个地址以显示在一个视图中。 我想每个子视图只显示其中两个,并使用分页来显示其余部分。 我使用 ngx 分页和响应式表单。

但不幸的是,分页无法正常工作。它只显示前两个地址(如果“pageSize”= 2),当我单击分页控件时没有任何变化。只有“currentPage”(p - 在我的例子中)的值会改变。

如果我检查我的公司对象,它会填充该公司的所有现有地址,但我没有让它们显示出来。

我做错了什么?

如果我更改“itmesPerPage”,我可以显示所有的现有地址的数量 - 就是这样。

为了测试,我使用了“拼接管”,但效果是一样的。我只能显示第一个地址,而从不显示 - 例如 - 最后一个。

如果我在视图中“检查”我的元素并单击控件,则可以识别页面更改但没有任何更改。

这是我的“公司详细信息组件”,用于创建抽象控件并从服务器加载数据:

ngOnInit()

 this.companyDetailForm = this.formBuilder.group(
      id: [null],
      companyName: [''],
      middleName: [''],
      lastName: [''],
      created: [null],
      status: [''],
      isDeleted: [null],
      contactAddresses: this.formBuilder.array([
        this.addContactAddressFormGroup()
      ])
);
//Load the data
this.route.data.subscribe(data => 
  this.company = data['company']; // 'company' = name (..resolve: company: ...) from route path in routes.ts
  this.companyDetailForm.patchValue(
   id: this.company.id,
   companyName: this.company.companyName,
   middleName: this.company.middleName,
   lastName: this.company.lastName,
   created: this.company.created,
   status: this.company.status,
   isDeleted: this.company.isDeleted,
   contactAddresses: this.company.contactAddresses
  );

  this.companyDetailForm.setControl('contactAddresses',
                                        this.setExistingContactAddresses(this.company.contactAddresses) );

  );

// initialize Form
addContactAddressFormGroup(): FormGroup 
return this.formBuilder.group(
  contactId: [null],
  addressId: [null],
  line1: ['Test'],
  line2: ['Test2'],
  line3: ['Test3'],
  city: [''],
  region: [''],
  postalCode: [''],
  country: [''],
  created: [''],
  status: [''],
  isDeleted: [null],
  addressType: [''],
);

setExistingContactAddresses(conAddSets: ContactAddress[]): FormArray 
const conAddFormArray = new FormArray([]);
conAddSets.forEach(cas => 
  conAddFormArray.push(this.formBuilder.group(
    line1: cas.line1,
    line2: cas.line2,
    line3: cas.line3,
    postalCode: cas.postalCode,
    city: cas.city,
    region: cas.region,
    country: cas.country
  ));
);
console.log(this.companyDetailForm);
return conAddFormArray;

视图的相关部分,魔法应该发生的地方:

.......

<div class col-sm-8>
        <div class="tab-panel">
            <tabset class="company-tabset">
                <tab heading="Addresses">
                  <div class="card-deck" style="width: auto">
                  <div formArrayName="contactAddresses"  *ngFor="let contactAddress of companyDetailForm['controls']['contactAddresses']['controls'] | paginate:  itemsPerPage: pageSize, currentPage: p  ; let i = index" >
                    <div [formGroupName]="i">
                      <div class="card">
                        <div class="card-header">

                        </div>
                        <div class="card-body" >
                          <div class="card-text">
                              <div class="form-group" aria-autocomplete="none">
                                  <strong><label for="line1">Street</label></strong>
                                  <input class="form-control" type="text" id="line1" formControlName="line1">
                                  <input class="form-control" type="text" id="line2" formControlName="line2">
                                  <input class="form-control" type="text" id="line3" formControlName="line3">
                              </div>
                              <div class="form-group" aria-autocomplete="none">
                                  <strong><label for="postalCode">Zip - City - Region</label></strong>
                                  <input class="form-control" type="text" id="postalCode" formControlName="postalCode">
                                  <input class="form-control" type="text" id="city" formControlName="city">
                                  <input class="form-control" type="text" id="region" formControlName="region">
                              </div>
                              <div class="form-group" aria-autocomplete="none">
                                  <strong><label for="country">Country</label></strong>
                                  <input class="form-control" type="text" id="country" formControlName="country">
                              </div>

                          </div>
                        </div>
                      </div>


                    </div>                                           

                  </div>                  

                  </div>

                  <div class="text-center mt-4">
                    <pagination-controls (pageChange)="p = $event" autoHide="true"></pagination-controls>
                    p
                  </div>                                           


                </tab>

我是 Angular 新手,如果有任何帮助,我们将不胜感激。

非常感谢提前 汤姆

【问题讨论】:

【参考方案1】:

在您的 html 模板中,当您对 contactAddresses 进行分页时,您会得到索引 i[0,1],[0,1] 等等。但角形索引仍在使用[0,1,2,3,4...n]。这可能就是问题所在。

创建一个函数,动态生成索引,例如generateIndex(i),返回i + pageSize * pageIndex

【讨论】:

【参考方案2】:

我遇到了同样的问题。 表单控件未更新,因为等于 iformGroupName 在不同页面上始终相同。 对于第 1 页,索引为 1 和 2, 对于第 2 页,再次是 1 和 2。 这是因为我们在 formArray 的分页部分循环。为了解决这个问题,我创建了一个从 pageSize、currentPage 和项目索引创建索引的函数。

接下来的想法是:

  fieldGlobalIndex(index) 
    return this.pageSize * (this.currentPage - 1) + index;
  

然后只需替换:

 [formGroupName]="i" -> [formGroupName]="fieldGlobalIndex(i)"

希望这会有所帮助。

【讨论】:

以上是关于Angular 6:在 *ngFor 中的 formArray 上使用 ngx-pagination 不会更改视图中的控件的主要内容,如果未能解决你的问题,请参考以下文章

Angular 6 *ngFor 为第一个,奇数,偶数和最后一个显示不同的样式

在 ngFor 的帮助下迭代 Angular5 中的 JSON 数组

ngFor(Angular 9)中的动态模板引用变量

*ngFor 中的 Angular 复选框

angular2中的[ngFor]和[ngForOf]有啥区别?

如何在Angular 2中选择ngFor中的所有过滤复选框?