NgFor и события щелчка

Я впервые перехожу с React на Angular и пытаюсь к нему привыкнуть. Как выполнить отдельное событие щелчка только для нужного элемента, а не для каждого элемента в моем списке JSON?

Служба Logout() работает. Если я этого не сделаю; используйте ngFor и передайте событие щелчка непосредственно в шаблон, который он делает то, что должен делать. Но не тогда, когда я передаю его из JSON в ngFor. Я полагаю, что всегда могу вернуться в другую сторону, но теперь мне любопытно. Забавно, я добавил alert() и событие срабатывает, а не AuthService в функции выхода...

Шаблон

<a
   *ngFor = "let usermenuitem of usermenu; let i = index"
   [routerLink] = "usermenuitem.link"
   (click) = "usermenuitem.goto()">
   {{usermenuitem.title}}
</a>

Компонент

export class AuthorisedTopNavComponent implements OnInit {

  usermenu:Object[] = [
    {
      title: 'Account',
      link: '/account',
      icon:"ua-home.svg",
      goto: ()=>{},
    },
    {
      title: 'Membership',
      link: '/membership',
      icon:"ua-home.svg",
      goto: ()=>{},
    },
    {
      title: 'Logout',
      link: '/',
      icon:"ua-home.svg",
      goto: this.logoff,
    },
  ]

  constructor (
    public authService: AuthService
  ) {}  

  ngOnInit() {}


  logoff() {
    this.authService.logout('/');
  }

}

вы пробовали ()=> this.logoff()?

Kevin Oswaldo 10.12.2020 19:59

Я подозреваю, что this не привязан к правильному контексту.

callback 10.12.2020 19:59

Попробуйте this.logoff.bind(this)

Owen Kelvin 10.12.2020 20:02

@OwenKelvin БУЯА!!!! Отлично сделано! если вам нужен кредит, получите ответ на этот вопрос. Спасибо

LOTUSMS 10.12.2020 20:06

Странно использовать [routerLink] и (click) в одном и том же теге. Я думаю, что использование goto:()=>this.logoff() может сработать, но я не уверен

Eliseo 10.12.2020 20:08

@Eliseo, это потому, что ngFor прикреплен к тегу <a>, который в некоторых случаях используется как событие щелчка, например выход из системы, и как ссылка на маршрутизатор в других случаях, которые служат только ссылкой на страницу.

LOTUSMS 10.12.2020 20:15

@LOTUSMS, попробуйте тогда [routerLink] = "usermenuitem.link?usermenuitem.link:null" (click) = "!usermenuitem.link && usermenuitem.goto()" или используйте роутер. Перейдите в функцию "goto"

Eliseo 10.12.2020 20:37

@Eliseo, я пытался проверить это, и это не сработало. Возможно, с некоторыми дополнительными настройками, но он работает так, как у меня сейчас.

LOTUSMS 11.12.2020 16:23
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
8
1 409
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы можете прикрепить событие клика к своему шаблону и передать объект меню пользователя

   <a
   *ngFor = "let usermenuitem of usermenu; let i = index"
   [routerLink] = "usermenuitem.link"
   (click) = "goto(usermenuitem)">
   {{usermenuitem.title}}
</a>

Компонент

export class AuthorisedTopNavComponent implements OnInit {

  usermenu:Object[] = [
    {
      title: 'Account',
      link: '/account',
      icon:"ua-home.svg",
      goto: ()=>{},
    },
    {
      title: 'Membership',
      link: '/membership',
      icon:"ua-home.svg",
      goto: ()=>{},
    },
    {
      title: 'Logout',
      link: '/',
      icon:"ua-home.svg",
      goto: this.logoff,
    },
  ]

  constructor (
    public authService: AuthService
  ) {}  

  ngOnInit() {}


  logoff() {
    this.authService.logout('/');
  }

 goto(usermenu){
  if (usermenu.title === 'logout'){
        this.logoff()
    }
 }

}

Надеюсь это поможет?

Спасибо, но я не думаю, что это хорошая практика. Это хороший хак, но он работает только в том случае, если в заголовке есть выход из системы. Если заголовок когда-либо менялся на выход из системы, выход из системы или что-то еще, то обработчик событий также должен быть изменен.

LOTUSMS 10.12.2020 20:17
Ответ принят как подходящий

Анализ проблемы

Шаги и функции кода работают так, как вы объяснили.

Служба Logout() работает. Если я этого не сделаю; используйте ngFor...

Так что же происходит? Почему служба не вызывается?

Рассмотрим шаги...

  1. Вы звоните *ngFor
<a (click) = "usermenuitem.goto()" ... >
<a (click) = "usermenuitem.goto()" ... >
<a (click) = "usermenuitem.goto()" ... >
...
  1. Теперь разбиваем usermenuitem.goto(). Для предыдущего это просто () => {}, так что они будут работать как положено. Наше внимание сосредоточено на goto: this.logoff,

Так что просто мы делаем что-то вроде ниже

const goto = this.logoff
goto()

class myObject {
  constructor() {
    this.name = 'Peter'
  }
  name = 'My Name';
  static sayName () {
    console.info('Say ' + this.name )
  }
}
console.info("Message 1 => ")
myObject.sayName()
console.info("Message 2 => ")
const p = myObject.sayName
p()

Если вы запустите приведенный выше код, вы увидите, что первый подход работает, а второй нет! Выдает ошибку, что this не определено.

Это проблема, с которой вы столкнулись. Ваш код теряет контекст this, поэтому не работает. Другие функции, такие как alert(), будут работать, но любая функция с this не будет работать.

Решение

Чтобы решить эту проблему, вам нужно только убедиться, что вы не потеряете контекст this.

Опция 1

Назначьте переменную для хранения this, например that = this. Я никогда не использовал эту опцию в angular, но хорошо работает в vanilla js.

Вариант 2

Просто привяжите this. Обычно это самый простой вариант. В вашей ситуации вы можете просто использовать this.logoff.bind(this), и ваш код должен работать

Вариант 3

Используйте функцию стрелки

Это самый простой вариант. Просто измените функцию logoff на

logoff = () => {
    this.authService.logout('/');
  }

Одним из gotcha этого подхода является то, что если вы используете TS версии 4+, вы можете столкнуться с проблемами, связанными с расположением свойств, в противном случае это работает.

Другие вопросы по теме