模板文件中仅允许数组和可迭代。异常行为

时间:2019-07-04 19:45:31

标签: angular typescript

在组件ts executeCommand方法中,我正在克隆这样一个已经存在的对象

let newCommandArray = new Object();
      newCommandArray = this.commandArray[commandId];

之后,我遍历newCommandArray并对数据进行一些操作。当我操纵克隆对象newCommandArray上的数据时,原始对象数据this.commandArray[commandId]也发生了变化,这使得模板无法呈现视图。在item.ParamProps.options中输入错误,

HTML第51行中的

Error trying to diff '"[{\"name\":\"option1\",\"value\":\"option1\"},{\"name\":\"option2\",\"value\":\"option2\"}]"'. Only arrays and iterables are allowed<md2-option *ngFor="let option of item.ParamProps.options">

我们将帮助您克服这一问题。

HTML模板:

 <div *ngSwitchCase="'select'">
                  <div class="form-group" *ngIf="item.ParamProps.visible">
                    <label>{{item.ParamName}}</label><br>
                    <div class="wrapper">
                      <md2-select [(ngModel)]="item.ParamValue"
                                  [name]="item.ParamID">
                        <md2-option *ngFor="let option of item.ParamProps.options"
                                    [value]="option.value">{{option.name}}
                        </md2-option>
                      </md2-select>
                      <i class="bar"></i>
                    </div>
                  </div>
                </div>

组件TS:

export class DynamicCommandComponent implements OnInit {
  public commands: ICommandList;
  public message: string;
  public commandArray: any;
  public commandHistoryList: any;
  public filterTerm: string;
  private itemId: any;
  @ViewChild('commandHistoryModal') commandHistoryModal: any;

  constructor(private commandService: DynamicCommandService, private globalDataService: GlobalDataService) {
    this.commands = null;
    this.commandArray = {};
    this.commandHistoryList = {};
    this.filterTerm = '';
  }

  public ngOnInit() {
    this.itemId = Number(this.globalDataService.getAgentID());
    this.commandService.getCommandsSet(this.itemId).subscribe((res: ICommandList) => {
      this.commands = res;
      this.storeCommands(res);
      this.loadAllCommandStatus(this.itemId);

    });
  }


  public executeCommand(commandId: number) {
    this.commandService.getUserFeatures().subscribe((res: any) => {
      this.commandArray[commandId].userID = res.userId;
      let itemIdArray = new Array<number>();
      itemIdArray.push(this.itemId);
      this.commandArray[commandId].ItemIDs = itemIdArray;
      this.commandArray[commandId].name = UUID.UUID();
      let newCommandArray = new Object();
      newCommandArray = this.commandArray[commandId];
      newCommandArray.CommandParamList[0].ParamProps.options = JSON.stringify(newCommandArray.CommandParamList[0].ParamProps.options);
      newCommandArray.CommandParamList.forEach(element => {
        element.ParamProps.options = JSON.stringify(element.ParamProps.options);
      });
      console.log(newCommandArray); // Output => [{\"name\":\"option1\",\"value\":\"option1\"},{\"name\":\"option2\",\"value\":\"option2\"}]"

      console.log(this.commandArray[commandId]); // Output => "[{\"name\":\"option1\",\"value\":\"option1\"},{\"name\":\"option2\",\"value\":\"option2\"}]"

      this.commandService.executeCommand(newCommandArray).subscribe();
    });
  }



}

1 个答案:

答案 0 :(得分:2)

您的代码有一些问题。

首先,在这些行中:

let newCommandArray = new Object();
newCommandArray = this.commandArray[commandId];

您实际上并没有克隆对象。首先将newCommandArray设置为一个空对象{},但随后您继续说'实际上,算了。 NewCommandArray将指向this.commandArray[commandId]。这就是为什么更改一个更改另一个更改的原因–两个变量名称都指向同一对象。

如果要实际克隆对象,则有无数种方法,每种方法都有优点和缺点,这取决于要克隆的对象的复杂性。有两种方法可以做到:

const newCommandArray = { ...this.commandArray[commandId] };

const newCommandArray = JSON.parse(JSON.stringify(this.commandArray[commandID]));

通过我使用const的方式,因为一旦分配了该对象,就不想将变量重新分配给另一个对象。您可以愉快地添加或更改其属性,而不会导致与使用const有关的任何错误。

然后,在两个地方无缘无故地对事物进行字符串化

newCommandArray.CommandParamList[0].ParamProps.options = JSON.stringify(newCommandArray.CommandParamList[0].ParamProps.options);
...
newCommandArray.CommandParamList.forEach(element => {
  element.ParamProps.options = JSON.stringify(element.ParamProps.options);
});

您为什么要对这些选项进行分类?无论如何,这就是为什么您遇到另一个问题,即ngFor感到困惑的原因。它想循环遍历一个数组,如果您没有将其转换为字符串的话,该数组就可以了!

如果您想了解有关克隆对象的更多信息,请看这里:

What is the most efficient way to deep clone an object in JavaScript?