javascript - forEach循环中持久存在的全局变量。范围问题?

时间:2018-02-18 21:59:17

标签: javascript arrays loops ecmascript-6 scope

我遇到一个循环遍历对象数组(两次)和修改嵌套对象的问题。

我有一组角色,其中包含分配给该角色的权限。我还有一组可以分配给角色的所有可能权限。

在我的html页面上,我需要列出每个角色......在每个角色中,我需要将所有权限列为复选框。如果已将权限分配给该角色,则需要检查权限复选框。要做到这一点,我需要:

  1. 遍历所有角色
  2. 对于每个角色,将所有附加权限的ID复制到数组中。
  3. 将角色的权限替换为所有权限列表。
  4. 遍历角色的新权限数组。
  5. 对于每个权限,添加一个新的“selected”属性,其值为true或false,具体取决于权限的ID是否在#2中设置的ID数组中
  6. 这是jsFiddle。这是操作:

    roles.forEach(function(role){
    
        // Get list of all the permission ids before the permissions are replaced with the list of all permissions
        var permission_ids = role.permissions.map(p => { return p.id });
    
        // Replace the roles permissions with the global list of permissions
        role.permissions = permissions;
    
        role.permissions.forEach(function(permission){
            permission.selected = permission_ids.indexOf(permission.id) > -1;
        });
    });
    

    问题是,权限变量绑定到本地role.permissions数组,并且每次迭代角色都会持久化。

    操作的结果应该是包含所有权限列表的角色列表,并且在每个权限中都有一个“selected”属性,具体取决于权限附加到角色。

    相反,最后......每个角色的权限是角色循环最后一次迭代操作的结果。

    我可以接受另一种解决方案,但我还想解释为什么会发生这种情况?

2 个答案:

答案 0 :(得分:0)

循环正常运行,但每个循环都会重置migrationBuilder.CreateTable( name: "GSRelatedProducts", columns: table => new { ParentProductId = table.Column<Guid>(nullable: false), ChildProductId = table.Column<Guid>(nullable: false), Optional = table.Column<bool>(nullable: false), Quantity = table.Column<int>(nullable: false) }, constraints: table => { table.PrimaryKey("PK_GSRelatedProducts", x => new { x.ParentProductId, x.ChildProductId }); table.ForeignKey( name: "FK_GSRelatedProducts_GSProducts_ChildProductId", column: x => x.ChildProductId, principalTable: "GSProducts", principalColumn: "Id", onDelete: ReferentialAction.NoAction); table.ForeignKey( name: "FK_GSRelatedProducts_GSProducts_ParentProductId", column: x => x.ParentProductId, principalTable: "GSProducts", principalColumn: "Id", onDelete: ReferentialAction.NoAction); }); 。大概你只是在循环结束后才使用那个值,并且看到变量只能容纳一个值,它始终是最后一个值。 最简单的解决方案是决定你想用role.permissions和permission.selected做什么,然后在循环中做(比如为每个角色创建html并输出到页面)

答案 1 :(得分:0)

您可以使用类似的内容来保证permissions阵列的安全。 但是你选择的数据结构对我来说很奇怪。

&#13;
&#13;
var roles = [{
    "id": 1,
    "name": "Viewer",
    "permissions": [{
        "id": 1,
        "name": "View all Posts"
      },
      {
        "id": 2,
        "name": "View a Single Post"
      }
    ]
  },
  {
    "id": 2,
    "name": "Editor",
    "permissions": [{
        "id": 1,
        "name": "View all Posts"
      },
      {
        "id": 2,
        "name": "View a Single Post"
      },
      {
        "id": 3,
        "name": "Add a Post"
      },
      {
        "id": 4,
        "name": "Edit a Post"
      }
    ]
  },
  {
    "id": 3,
    "name": "Moderator",
    "permissions": [{
        "id": 1,
        "name": "View all Posts"
      },
      {
        "id": 2,
        "name": "View a Single Post"
      },
      {
        "id": 4,
        "name": "Edit a Post"
      },
      {
        "id": 5,
        "name": "Delete a Post"
      },
      {
        "id": 6,
        "name": "Flag a Post"
      }
    ]
  }
];

var permissions = [{
    "id": 1,
    "name": "View all Posts"
  },
  {
    "id": 2,
    "name": "View a single Post"
  },
  {
    "id": 3,
    "name": "Add a Post"
  },
  {
    "id": 4,
    "name": "Edit a Post"
  },
  {
    "id": 5,
    "name": "Delete a Post"
  },
  {
    "id": 6,
    "name": "Flag a Post"
  }
];

roles.forEach(function(role) {

  console.log("On role: " + role.name);

  permissions.forEach(function(permission) {
    var role_permission = role.permissions.filter(e => e.id === permission.id)[0];
    if (!role_permission)
      role.permissions.splice(permission.id - 1, 0, Object.assign({selected: false}, permission));
    else role_permission.selected = true;
  });
  console.log(JSON.stringify(permissions))
  console.log(JSON.stringify(role.permissions));
});
&#13;
&#13;
&#13;