本文介绍了Angular 5 从服务到组件再到模板获取数据的数组问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尝试在模板 HTML 中显示从组件到服务调用的数据,该调用调用并返回 API,但出现此错误

错误错误:找不到类型为object"的不同支持对象[object Object]".NgFor 仅支持绑定到可迭代对象,例如数组.

HTML

  • <a [routerLink]="[item.url]" ><span>{{item.name}}</span></a>
  • 组件

    测试:任何;this.arsService.getMenu().订阅(结果 =>{this.testing = 结果;console.log('menu',result);},错误 =>{console.log('菜单错误', 错误);})

    服务:

    getMenu() {返回 this.http.post(this.menuUrl, JSON.stringify({用户 ID":61525,应用程序ID":15,"NavAppID":null,应用程序组ID":116,"SelectedCaseID": 0,选定角色ID":0}), httpOptions).map((响应:响应)=>{返回响应;})}

    数据图片截图

    更新

    我发现数据有问题

    "menu" 有 data: 和它是什么在这里而不是工作.

    有效的来自不同的 API 调用注意是有

    数据:数组(16)

    如何将数据从对象固定到数组?

    解决方案

    试试这个:*ngFor="let item of testing.data.Menu1Items".我不相信你需要异步管道.我也会 *ngIf 哪个 div 包含 *ngFor 循环.

    像这样:

    <li *ngFor="let item of testing.data.Menu1Items"><a [routerLink]="[item.url]" ><span>{{item.name}}</span></a>

    让我知道这是否有助于您实现目标.

    所以我建议在向您的客户返回响应时以不同的方式格式化您的数据,这就是我在返回数据之前格式化数据的方式:

    [{动作类型:'',displayName: 'MyiCIS',显示顺序:'1',displayOrder1:空,groupName: '数据输入',编号:420,url: 'MyiCIS.asp',类型:'Menu1Items'},{动作类型:'',displayName: 'MyiCIS',显示顺序:'1',displayOrder1:空,groupName: '数据输入',编号:420,url: 'MyiCIS.asp',类型:'Menu1Items'},{动作类型:'',displayName: 'MyiCIS',显示顺序:'1',displayOrder1:空,groupName: '数据输入',编号:420,url: 'MyiCIS.asp',类型:'Menu2Items'},{动作类型:'',displayName: 'MyiCIS',显示顺序:'1',displayOrder1:空,groupName: '数据输入',编号:420,url: 'MyiCIS.asp',类型:'Menu2Items'}];

    那么如果你想按你选择的任何字段对数据进行分组,通过这个方法运行数组,它会吐出分组到单独数组中的数据:

    transformArray(array: Array

    所以第一个数组就是应该从服务器返回的,第二个数组是转换后的.

    然后在你的标记中循环,这里是 *ngFor 的结构:

    <div>{{ category.key }}</div><div *ngFor="let item of category.value">{{ 值.名称 }}

    我希望这会有所帮助,我认为您的第一步应该是在将该数组返回给客户端之前将该数组格式化为未按键分组的对象数组,然后在数据到达您的客户端后对其进行操作.

    Trying to display data in template HTML from a component to service call which calls and returns an API, but I'm getting this error

    HTML

    <li *ngFor="let item of testing">
       <a [routerLink]="[item.url]" >
        <span>{{item.name}}</span>
       </a>
    </li>
    

    Component

    testing: any;
    
    this.arsSevice.getMenu()
         .subscribe(
             result => {
                this.testing = result;
                console.log('menu',result);
          },
          error => {
             console.log('menu error', error);
          }
          )
    

    Service:

    getMenu()  {
        return this.http.post(this.menuUrl, JSON.stringify({
            "UserID": 61525,
            "AppID": 15,
            "NavAppID":null,
            "AppGroupID": 116,
            "SelectedCaseID": 0,
            "SelectedRoleID":0
        }), httpOptions)
            .map((response: Response)=> {
                return response;
            })
    }
    

    Image screenshot of the data

    Update

    I see a data problem

    "menu" has data: and it what is HERE and NOT working.

    the working one is from a different API callNotice that is has

    How can I fix my data from object to array ?

    解决方案

    Try this: *ngFor="let item of testing.data.Menu1Items". I do not believe you need the async pipe for this. I would also *ngIf which ever div is containing the *ngFor loop.

    Like so:

    <div *ngIf="testing">
        <li *ngFor="let item of testing.data.Menu1Items">
           <a [routerLink]="[item.url]" >
            <span>{{item.name}}</span>
           </a>
        </li>
    </div>
    

    Let me know if this can help out with what you are trying to achieve.

    EDIT:

    So I would suggest formatting your data differently when returning a response to your client, this is how I would format the data before its returned:

    [
      {
        actionType: '',
        displayName: 'MyiCIS',
        displayOrder: '1',
        displayOrder1: null,
        groupName: 'Data Entry',
        id: 420,
        url: 'MyiCIS.asp',
        type: 'Menu1Items'
      },
      {
        actionType: '',
        displayName: 'MyiCIS',
        displayOrder: '1',
        displayOrder1: null,
        groupName: 'Data Entry',
        id: 420,
        url: 'MyiCIS.asp',
        type: 'Menu1Items'
      },
      {
        actionType: '',
        displayName: 'MyiCIS',
        displayOrder: '1',
        displayOrder1: null,
        groupName: 'Data Entry',
        id: 420,
        url: 'MyiCIS.asp',
        type: 'Menu2Items'
      },
      {
        actionType: '',
        displayName: 'MyiCIS',
        displayOrder: '1',
        displayOrder1: null,
        groupName: 'Data Entry',
        id: 420,
        url: 'MyiCIS.asp',
        type: 'Menu2Items'
      }
    ];
    

    Then if you want to group the data by whichever field you choose, run the array through this method and it will spit out the data grouped into separate arrays:

    transformArray(array: Array<any>, field) {
        if (array) {
          const groupedObj = array.reduce((prev, cur) => {
            if (!prev[cur[field]]) {
              prev[cur[field]] = [cur];
            } else {
              prev[cur[field]].push(cur);
            }
            return prev;
          }, {});
          return Object.keys(groupedObj).map(key => ({ key, value: groupedObj[key] }));
        }
        return [];
      }
    

    Here is a console log of the data before its transformed and then after its been transformed:

    So the first array is just what should be returned from the server, and the second array is after the transformation.

    Then to loop through this in your markup, here is the structure of the *ngFor:

    <div *ngFor"let category of data">
      <div>{{ category.key }}</div>
      <div *ngFor="let item of category.value">
        {{ value.name }}
      </div>
    </div>
    

    I hope this can be of help, I think your first step should be formatting that array before its returned to the client as an array of objects not grouped by a key, and then manipulate the data once it hits your client.

    这篇关于Angular 5 从服务到组件再到模板获取数据的数组问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

    09-02 04:21