Angular Оператор распространения не работает должным образом? - PullRequest
1 голос
/ 14 апреля 2020

Я пытаюсь обработать массив в angular. Мне нужно получить имя пользователя-администратора из массива и попробовать следующий подход

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

Ответы [ 5 ]

4 голосов
/ 14 апреля 2020

Я бы изменил логи фильтра c, чтобы избежать каких-либо побочных эффектов.

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) 
2 голосов
/ 14 апреля 2020

users является ссылочным типом. Таким образом, вам нужно создать глубокую копию объекта. Попробуйте использовать метод JSON.parse для создания глубокой копии объекта:

let usersList = [...JSON.parse(JSON.stringify(users))]
0 голосов
/ 14 апреля 2020

Оператор распространения в массиве делает только то, что расширяет массив. При использовании этого метода вы просто передаете эквивалентное количество аргументов методу 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;
}
0 голосов
/ 14 апреля 2020

Прежде всего, операция распространения не будет работать,

Причина, это полезно только для однослойной структуры данных, то есть массива примитивных типов данных, для массива объектов он не создает глубокую копию, когда вложенные свойства находятся на рисунке.

Поэтому вам следует использовать метод Lodashs cloneDeep.

ОБНОВЛЕНО

установить loda sh в ваш angular проект

Затем импортировать его как

import {cloneDeep} из 'loda sh'; Цитируйте

и используйте его как

  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]
  }

Это должно решить вашу проблему здесь ?

0 голосов
/ 14 апреля 2020

В вашей функции замените 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]
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...