Búsqueda de sitios web

typescript - Componente de atributo de Angular con valor


Usando Angular 6.0.7, estoy creando un componente de atributo e inyectando un valor en él. Para esto, estoy siguiendo la respuesta aquí.

Quiero saber si hay una manera, al igual que en AngularJS, de introducir un valor directamente en el componente, sin la necesidad de definir un [form]="" separado. Por ejemplo: <div my-component="form">.

El html

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

El componente de atributo

@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);    
  }
}

El console.warn(this.form) resulta en 'undefined'.

Lo que estoy intentando hacer

Estoy intentando inyectar mi formulario (a través de la variable #loginForm) en el componente, pero no quiero hacer otro enlace, como [form]="loginForm". Según la publicación aquí, esto debería ser posible, pero no puedo lograr que funcione. ¿Ha cambiado esto desde una versión más alta de Angular o estoy haciendo algo mal aquí?

He intentado

He intentado enlazar la entrada a la variable @Input mediante enlace explícito, @Input('form') private form: NgForm, pero esto también resultó en 'undefined'.

También intenté revertir o cambiar las comillas validate-on-submit="loginForm" o validate-on-submit="'loginForm'", pero en algunos de los intentos esto resulta en que Angular no reconozca el selector del componente en absoluto.

Solución

Con la respuesta de @user184994 he logrado cambiar mi código y hacerlo funcionar. Esto resultó en el siguiente código:

html

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

componente

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

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

Tenga en cuenta que el selector está rodeado con [] para indicar que es una directiva de Angular y que está inyectando algo y haciendo referencia a @Input("validate-on-submit"), ya que una propiedad no puede tener guiones en su nombre.

También ten en cuenta que he cambiado el decorador @Component a @Directive, ya que no realizará ninguna manipulación del DOM, no es necesario tener una vista. Más información aquí.

Respuesta #1

Necesitas crear un campo de entrada con el mismo nombre que el selector de atributo. Por ejemplo,

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

  @Input() hello: string;

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

Puedo usar esto como <div hello="Test" ></div>, y el valor Test se pasará.

Ejemplo de trabajo aquí.

Artículos relacionados