Mr.wiseguy
Mr.wiseguy

Reputation: 4252

Angular attribute component with value

Using Angular 6.0.7, I am creating an attribute component and injecting a value into it. For this I am following the answer here.

I want to know if there is a way, just like in AngularJS, to input a value directly into the component, without the need to define a separate [form]="". For example: <div my-component="form">.


The html

<form (ngSubmit)="login(loginForm.form.valid)" 
      #loginForm="ngForm"
      validate-on-submit='"loginForm"'>
</form>

The attribute component

@Component({
  selector: '[validate-on-submit="form"]',
  template: `<ng-content></ng-content>`
})
export class ValidateOnSubmitComponent implements OnInit {

  @Input() private form: NgForm;

  public ngOnInit(): void {
    console.warn(this.form);    
  }
}

The console.warn(this.form) results in 'undefined'.


What I am trying to do

I am trying to Inject my form (via the variable #loginForm) into the component, but I do not want to make an other binding, like [form]="loginForm". According to the post here this should be possible, but I cannot make it to work. Has this changed since a higher Angular version or am I doing something wrong here?


I have tried

I have tried to bind the input to the @Input variable via explicit binding, @Input('form') private form: NgForm, but this alo resulted in 'undefined'.

I also tried to revert or change the quotes validate-on-submit="loginForm" or validate-on-submit="'loginForm'", but in some of the tries this results in Angular not reconizing the component selector at all.


Solution

With the answer of @user184994 I've managed to change my code and get it working. This resulted in the following code:

html

<form (ngSubmit)="login(loginForm.form.valid)" 
      #loginForm="ngForm"
      [validate-on-submit]="loginForm">
</form>

component

@Directive({
  selector: "[validate-on-submit]"
})
export class ValidateOnSubmitComponent {

  @Input("validate-on-submit") private form: NgForm;
}

Note that the selector is surrounded with [] for indicating that it is an Angular directive and you are injecting something and there reference to @Input("validate-on-submit"), since a property cannot have dashes in it's name.

Also note that i've change the @Component decorator to @Directive, since it won't be doing any DOM manipulation it is not necessary to have a view. More info here.

Upvotes: 5

Views: 15294

Answers (2)

Akj
Akj

Reputation: 7231

You Solution here

HTML:

app.component.html

<form (ngSubmit)="login()"
      #loginForm="ngForm"
      validateonsubmit ="{{loginForm.valid}}" >
</form>

hello.component.html:

form is valid : {{validateonsubmit}}

TS:

import { Component, Input } from '@angular/core';
import {NgForm } from '@angular/forms'

@Component({
  selector: '[validateonsubmit]',
  templateUrl:'./hello.component.html',
  styles: [`h1 { font-family: Lato; }`]
})
export class HelloComponent  {
  @Input() validateonsubmit : NgForm;

  public ngOnInit(): void {
    console.warn(this.validateonsubmit);    
  }

  login(bool){
    console.log(bool);
  }
}

Upvotes: 0

user184994
user184994

Reputation: 18301

You need to create an input with the same name as the attribute selector. For example,

@Component({
  selector: '[hello]',
  template: `<h1>Hello {{name}}!</h1>`,
  styles: [`h1 { font-family: Lato; }`]
})
export class HelloComponent  {

  @Input() hello: string;

  ngOnInit() {
    console.log(this.hello);
  }
}

I can use this like <div hello="Test" ></div>, and the value Test will be passed in.

Working example here.

Upvotes: 12

Related Questions