Reputation: 2046
I am making a 'skip to content' link. The link is in app.component and the content is in login.component, along with the target.
I've tried several methods, none of which worked out. So now I'm trying emitter/listener:
app.component (emitter):
import { Component, Output, EventEmitter} from '@angular/core';
export class AppComponent {
@Output() skipToCtrl: EventEmitter<any> = new EventEmitter();
skipLink() {
this.skipToCtrl.emit();
}
}
<a href="#content-start" (click)="skipLink()">Skip to main content</a>
login.component (listener):
<input type="text" #firstControl name="username" />
Don't know how login can subscribe to the event from within login. I keep finding articles that say not to do it How to subscribe to an event on a service in Angular2? but no articles that describe how to do it.
Upvotes: 5
Views: 12926
Reputation: 2212
100% Working!!!! It's basically a patch using Javascript:
Make a hidden input element in which component(app.component in your case) you need to call
<input type="hidden" id="getdata" (click)="Mydata();">
Here Mydata will be function in app.component
And call/Click this from other component(Login) using javascript:
document.getElementById('getdata').click();
Upvotes: -1
Reputation: 650
You're putting the event emitter in the wrong component for one. Event emitter is for child -> parent communication. So you'd probably want to put that in your login-component, if you want it to do anything.
login.component.ts
export class LoginComponent {
@Output() skipToCtrl: EventEmitter<any> = new EventEmitter();
emitSkipEvent(): void {
this.skipToCtrl.emit(true);
}
}
app.component.html
<login-component (skipToCtrl)="skipLink()">
There's a problem with my solution though, that event will never get emitted because I never call loginComponent.emitSkipEvent, I don't think EventEmitter behavior is what you're looking for as you want to pass data from the parent to the loginComponent. You probably want to put an @Input parameter on your login component and implement onChanges to handle the behavior. BETTER ANSWER :
import {OnChanges} from '@angular/core'
export class LoginComponent implements OnChanges {
@Input() skipToCtrl: boolean;
ngOnChanges(){
if(skipToCtrl){
// handle login component behavior changes here. Looks like you want to focus on the input
document.querySelector('input').focus();
}
}
}
Then in your app.component.ts you'd create a boolean variable to toggle
linkClicked:boolean;
Then in your app.component.html you can change the click behavior and bind the linkClicked to your login component's skipToCtrl boolean :
<a href="#content-start" (click)="linkClicked = true">Skip to main content</a>
<login-component [skipToCtrl]='linkClicked'>
Now when you click the link it will get passed down to the login component, and the OnChanges logic will fire.
Upvotes: 0
Reputation: 54731
Event emitters are used to add output into the templates. Using the round brackets ()
for binding to the event.
When you create a component:
@Component({...})
public export FooComponent {
@Output() name: EventEmitter = new EventEmitter<string>();
}
The above component now has an attribute that can be used with the ()
brackets in another template.
In another template:
<foo (name)="// code here //"></foo>
When the event is emitted (by calling this.name.emit("value")
) the above "code here" expression is executed by Angular. The emit
function takes a single argument which is passed to the expression as a $event
variable.
To have another component receive these events is to use the expression in that other component's template.
Let's create a Bar
component
@Component({...})
export class BarComponent {
public setName(value:string) {
console.log(value); // will output "chicken"
}
}
The above component has this template:
<foo (name)="setName($event)"></foo>
Now in the Foo
component we emit a value.
@Component({...})
public export FooComponent implements OnInit {
@Output() name: EventEmitter = new EventEmitter<string>();
public ngOnInit() {
this.name.emit("chicken");
}
}
This creates one-way communication from the Foo
component to the Bar
component via the template expressions.
Upvotes: 6
Reputation: 4402
in the login.component, u can write
<input type="text" #firstControl (skipToCtrl)="callsomemethod($event)" name="username" />
Upvotes: 0