使用ngModel的ngrx / store导致了一些问题

时间:2019-11-13 03:46:19

标签: javascript angular typescript redux ngrx

我正在使用primeng可编辑表和ngrx / store。该表值来自存储区:results

父组件:

this.results$ = store.pipe(select(mySelectors.results));

使用异步将其传递给子组件[results]="results$|async"

在子模板中:

<p-table [value]="results">
...
<ng-template pTemplate="body" let-rowData let-rowIndex="rowIndex">
  <tr [pSelectableRow]="rowData">
  ...
    <td pEditableColumn>
      <p-cellEditor>
        <ng-template pTemplate="input">
          <input pInputText type="text" [(ngModel)]="rowData.name">   // it's about this input
        </ng-template>
        <ng-template pTemplate="output">
          {{rowData.name}}
        </ng-template>
      </p-cellEditor>
    </td>
  </tr>
</ng-template>

结果模型如下:

{
 ...
 name: string;
 ...
}

我使用了ngrx-store-freeze。现在的问题是,商店的结果不能直接更改。因此,即使我尝试使用操作来更改存储中的值,但是我无法使用[(ngModel)]="rowData.name"从输入标签中获取更改后的值,也会导致它是只读的。

那么如何从输入标签中获取更改后的值,或者有更好的方法呢?我了解ngModel与ngrx / store有某种冲突,因此我尝试了深复制results并将其绑定到表,但是它不起作用,深复制仍然是只读的。

我被困在这里。请帮助我

3 个答案:

答案 0 :(得分:0)

Ngrx存储冻结会阻止您修改rowData.names的状态,因为您正在使用表示可以修改状态的输入。

因此您可以通过删除2种方式绑定来解决此问题

<input pInputText type="text" [ngModel]="rowData.name"> 

答案 1 :(得分:0)

如果要使用ngModel与来自可观察对象的数据进行两种方式绑定,则应先将其克隆到模板变量中,然后再开始对其进行修改。否则,您将变异商店数据。我使用克隆管道

<ng-container *ngIf="results$ | async | clone as results">
  Do what you want with results as it wont mutate the store because it is a clone
</ng-container>

我的克隆管道看起来像

@Pipe({
  name: 'clone'
})
export class ClonePipe implements PipeTransform {
  transform(value: any, args?: any): any {
    return clone(value);
  }
}

克隆函数看起来像

export const clone = obj =>
  Array.isArray(obj)
    ? obj.map(item => clone(item))
    : obj instanceof Date
    ? new Date(obj.getTime())
    : obj && typeof obj === 'object'
    ? Object.getOwnPropertyNames(obj).reduce((o, prop) => {
        o[prop] = clone(obj[prop]);
        return o;
      }, {})
    : obj;

它不会克隆每个JavaScript对象,但对于通过JSON来自API的任何内容都很好。

答案 2 :(得分:0)

问题解决了。将ngrx-store-freeze与primeng可编辑表结合使用可能会出现一些错误。 当超出p表时,一切都会好的。