【问题标题】:Angular Spread Operator not working properly?角度扩展运算符无法正常工作?
【发布时间】:2020-07-27 12:39:39
【问题描述】:

我正在尝试以角度处理数组。我需要从数组中获取管理员用户名并尝试以下方法

export class AppComponent  {
  adminName = ''
  data = {
    id:1,
    name:'Test User One',
    users:[
      {id:1,name:'User 2',role:'Management Admin'},
      {id:2,name:'User 3',role:'User'},
      {id:3,name:'User 1',role:'Profile Admin'},
    ]
  }

  ngOnInit(){
     this.getAdminName(this.data.users)
  }

  getAdminName(users){
   let name = ''
    name = users.filter((user)=>{
      user.role = user.role.replace(/\s/g, '-').toUpperCase()
      return user.role === 'PROFILE-ADMIN'
    }).map(row=>{
      return row.name
    })
    this.adminName = name[0]
  }
}

这是有效的,我可以获得 adminName 但它也改变了数据对象的角色并像这样转换对象

{
  "id": 1,
  "name": "Test User One",
  "users": [
    {
      "id": 1,
      "name": "User 2",
      "role": "MANAGEMENT-ADMIN"
    },
    {
      "id": 2,
      "name": "User 3",
      "role": "USER"
    },
    {
      "id": 3,
      "name": "User 1",
      "role": "PROFILE-ADMIN"
    }
  ]
}

我明白为什么会发生这种情况,我尝试使用扩展运算符,但它不起作用我尝试了以下方法

接近一个

this.getAdminName([...this.data.users]) // passing from here using spread operator

第二次接近

getAdminName(users){
   let usersList = [...users]
   let name = ''
    name = usersList.filter((user)=>{
      user.role = user.role.replace(/\s/g, '-').toUpperCase()
      return user.role === 'PROFILE-ADMIN'
    }).map(row=>{
      return row.name
    })
    this.adminName = name[0]
  }

我可以像下面那样做

getAdminName(users){
   let name = ''
   let role;
    name = users.filter((user)=>{
      role = user.role //used a variable in which holds 
      role = role.replace(/\s/g, '-').toUpperCase()
      return role === 'PROFILE-ADMIN'
    }).map(row=>{
      return row.name
    })
    this.adminName = name[0]
  }

但我想使用传播运算符方法来做到这一点,所以请建议我哪里出错了

Stackblitz 链接在这里

https://stackblitz.com/edit/angular-rjnytr

【问题讨论】:

  • user.role = user.role.replace(/\s/g, '-').toUpperCase() 这将修改用户角色。如果不将其分配给user.role,您就不能检查吗?
  • 是的,我知道,我在我的问题中解释过,我在仅从扩展运算符创建副本时遇到问题
  • 为什么要使用扩展语法?您可以在不更改数据本身的情况下过滤掉任何元素。我认为没有必要先对数组进行浅拷贝。
  • 坦率地说,这种方法是不必要的。只要您使用user.role = user.role.replace(/\s/g, '-').toUpperCase(),再多的传播运算符都不会给出想要的结果
  • 好的,你能告诉我哪个更好,这将帮助我了解正确的方法

标签: javascript angular


【解决方案1】:

users 是一个引用类型。因此,您需要创建对象的深层副本。尝试使用JSON.parse 方法创建对象的深拷贝:

let usersList = [...JSON.parse(JSON.stringify(users))]

【讨论】:

  • 在这种特定情况下,这可能有效,但通常,使用这种“深度复制”方法,您将丢失对象的任何功能和不可枚举的属性此外,@ 中已经涵盖了深度复制987654321@manyduplicates...
【解决方案2】:

在您的函数中,将user.role = user.role.replace(/\s/g, '-').toUpperCase() 替换为一个新变量,即:

getAdminName(users){
   let usersList = [...users]
   let name = ''
    name = usersList.filter((user)=>{
      let role = user.role;
      role = role.replace(/\s/g, '-').toUpperCase()
      return role === 'PROFILE-ADMIN'
    }).map(row=>{
      return row.name
    })
    this.adminName = name[0]
  }

【讨论】:

  • 这与用户在他们的问题中的相同,只是它在role 的定义前面有let。这很棒,但是...
【解决方案3】:

我会更改过滤器逻辑以避免任何副作用。

getAdminName(users) {
  const name = users
    .filter(user => user.role.replace(/\s/g, '-').toUpperCase() === 'PROFILE-ADMIN')
    .map(row => row.name);

  return name ? name[0] : '';
}

这样您就不需要考虑展开运算符的工作原理了。

this.getAdminName(this.data.users) 

【讨论】:

    【解决方案4】:

    首先Spread操作不行,

    原因,它仅对单层数据结构有用,即原始数据类型数组,对于对象数组,当嵌套属性在图片中时,它不会创建深层副本。

    所以你应该使用 Lodashs cloneDeep 方法。

    更新

    在你的 Angular 项目中安装 lodash

    然后像这样导入

    从“lodash”导入 { cloneDeep }; 块引用

    并像使用它一样,

      getAdminName(users){
       let usersList = cloneDeep(users);
       let name = ''
        name = usersList.filter((user)=>{
          user.role = user.role.replace(/\s/g, '-').toUpperCase()
          return user.role === 'PROFILE-ADMIN'
        }).map(row=>{
          return row.name
        })
        this.adminName = name[0]
      }
    

    这应该可以解决您的问题?

    【讨论】:

    • 如果它解决了您的问题,请给我点赞并接受我的回答。
    • 你自己试过了吗?它会给出与 OP 相同的结果
    • 你可以把这段代码粘贴到那里,自己验证
    • 生活就是这样......别担心,继续编码和回答:)
    • @Indrajeet 您的代码仍然修改了原始数据(user.role = user.role.replace(...)
    【解决方案5】:

    数组上的扩展运算符只是扩展数组。在您使用它的方式中,您只需将等量的参数传递给 getAdmin() 方法或 userList 变量作为数组中的元素。

    试试这样的:

    ngOnInit(){
     this.getAdminName(this.data.users)
    }
    
    getAdminName(users){
       const adminUser = users.find(({ role }) => {
         role = role.replace(/\s/g, '-').toUpperCase()
         return role === 'PROFILE-ADMIN'
       });
       this.adminName = adminUser.name;
    }
    

    【讨论】:

      猜你喜欢
      • 2021-05-13
      • 2015-11-27
      • 2015-04-25
      • 1970-01-01
      • 2017-05-03
      • 1970-01-01
      • 1970-01-01
      • 2021-02-06
      • 1970-01-01
      相关资源
      最近更新 更多