Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2 - How to listen to event without a template?

Tags:

The Problem

Normally, in Angular 2, one would listen to an event via the following syntax:

<my-elem (customEvent)="customEventProcessor"></my-elem>

But when I use a router, that host - <my-elem> - does not exist in any template. Instead, there's a <router-outlet>, and my component is loaded upon navigation. Thus, the crux of my problem is, How can I force my host to listen to my custom event without relying on a template?

Optional Details

Suppose I have some element list-view, which is a child of my root component. list-view listens for a custom event via the normal syntax:

<list-view (customEvent)="customEventProcessor()"></list-view>

Just for completeness, the list-view component that emits the event also has a predictable structure:

<button (click)="onDetailsClick(propertyOfInterest)">Click here</button>

The list-view sends the event up to the parent via observation.

class ListView {

    ...

        public onDetailsClick(property: string): void {

            this.customEvent.next({ value: property });
    
        }

}

and that event triggers the customEventProcessor() function. So far so good. However, when I use a router to control whether list-view is present, I cannot (to my knowledge) insert a command to monitor some event.

I am not sure what the best approach is to handle this case.

like image 996
Jefftopia Avatar asked Nov 15 '15 03:11

Jefftopia


People also ask

Which is used for listening to user events in Angular?

@HostListener is Angular's decorator method that's used for listening to DOM events on the host element of both component and attribute directives.

What does $event mean in Angular?

The $event object often contains information the method needs, such as a user's name or an image URL. The target event determines the shape of the $event object. If the target event is a native DOM element event, then $event is a DOM event object, with properties such as target and target.

How does Angular handle click event?

Events are handled in Angular using the following special syntax. Bind the target event name within parentheses on the left of an equal sign, and event handler method or statement on the right. Above, (click) binds the button click event and onShow() statement calls the onShow() method of a component.

What is the type of $event in Angular?

The event you passed through $event is a DOM event, therefore you can use the EventName as the type. The MouseEvent interface represents events that occur due to the user interacting with a pointing device (such as a mouse). Common events using this interface include click, dblclick, mouseup, mousedown.


1 Answers

This problem isn't resolved yet (see this github issue). Here is one of the possible solutions at this moment (see this plunk):

@Component({
  selector: 'my-app',
  directives: [RouterOutlet, RouterLink],
  template: `
    <h1>{{ message }}</h1>
    <a [router-link]="['./MyElem1']">MyElem1</a>
    <a [router-link]="['./MyElem2']">MyElem2</a>
    <router-outlet></router-outlet>
  `
})
@RouteConfig([
  { path: '/', redirectTo: '/my-elem1' },
  { path: '/my-elem1', name: 'MyElem1', component: MyElem1 },
  { path: '/my-elem2', name: 'MyElem2', component: MyElem2 },
])
export class App {
  message: string = 'Click on the button';

  @ViewChild(MyElem1) myElem1: MyElem1;
  @ViewChild(MyElem2) myElem2: MyElem2;

  constructor(router: Router) {
    let subs = null;
    router.subscribe(() => {
      if (subs) { subs.unsubscribe(); subs = null; }

      if (this.myElem1) {
        subs = this.myElem1.customEvent1.subscribe(m=>this.processCustomEvent(m));
      }
      if (this.myElem2) {
        subs = this.myElem2.customEvent2.subscribe(m=>this.processCustomEvent(m));
      }
    });
  }

  processCustomEvent(message) { this.message = message }
}
like image 102
alexpods Avatar answered Oct 05 '22 13:10

alexpods