Как создать собственный компонент текстового поля в Angular 9 - PullRequest
2 голосов
/ 28 мая 2020

Я хочу создать некоторые общие компоненты для тегов HTML в Angular 9, например текстовое поле.

Родительский компонент HTML:

<form (ngSubmit)="onSubmit()">
            <textbox [name]="'articleDto.articleName'" (changeEvent)="txtChange($event)" [label]="'Article Name'" [placeholder]="'Article Name'"></textbox>
            <textbox [name]="'articleDto.titleName'" [label]="'Title Name'" [placeholder]="'Title Name'"></textbox>
          <button type="submit" class="btn btn-success mr-2">Submit</button>
</form>

Код TS родительского компонента:

import { Component, OnInit } from '@angular/core';
import { spinx } from '../core/lib/spinx.service';
import Swal from 'sweetalert2';

@Component({
  selector: 'app-new-article',
  templateUrl: './new-article.component.html'
})
export class NewArticleComponent implements OnInit {

  articleDto:any = {};
  constructor(private spinxService: spinx) { }

  ngOnInit(): void {
  }

  txtChange(event){
    alert(this.articleDto.articleName)
  }
}

TS дочернего компонента:

import { Component, forwardRef, Input, Output, EventEmitter } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
@Component({
  selector: 'textbox',
  template: `
  <div class="form-group">
  <label>{{label}}</label>
  <input type="text" name="{{name}}" [(ngModel)]="{{name}}" (change)="changeComplete()" class="form-control" placeholder="{{placeholder}}">
  </div>
  `,
  providers: [
    {provide: NG_VALUE_ACCESSOR, useExisting: TextboxComponent, multi: true}
  ]
})
export class TextboxComponent  {
  @Input() placeholder: string;
  @Input() name: string;
  @Input() label: string;
  @Output()
  changeEvent = new EventEmitter<string>();
  changeComplete() {
    this.changeEvent.emit('complete');
  }
}

Я не могу использовать [(ngModel)]="{{name}}" в дочернем компоненте, который сопоставлен с родительским компонентом.

Пожалуйста, предоставьте решение / предложение для этого. Спасибо!

1 Ответ

4 голосов
/ 28 мая 2020

При выполнении двусторонней привязки данных с ngModel соответствующий синтаксис:

 [(ngModel)]="name"

Интерполяция не требуется для имени переменной.

Обновление: 1. Если компоненты имеют отношения родитель / потомок, как в вашем случае, вы можете обмениваться данными между ними через декораторы @Input () и @Output ().

Обмен данными от родительского к дочернему с помощью @Input ():

<h3>Parent Component</h3>

<label>Parent Component</label>c
<input type="number" [(ngModel)]='parentValue'/>

<p>Value of child component is: </p>
<app-child [value]='parentValue'></app-child>

А в дочернем компоненте 'parentValue' можно получить как:

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

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {

  @Input() value: number;
  constructor() { }

  ngOnInit() {
  }

}

Теперь, в случае отправки данных от Child to Parent, мы можем использовать @Output ( ) эмиттер событий. Таким образом, у родителя будет функция для получения данных от потомка как:

parent-app.component.html 
    <app-child [value]="parentValue" (childEvent)="childEvent($event)"></app-child>

parent-app.component.ts

childEvent(event) {
console.log(event);
}

And, the child.component.ts would look like :

import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {

  @Input() PData: number;
  @Output() childEvent = new EventEmitter();
  constructor() { }
  onChange(value) {
    this.childEvent.emit(value);
  }

  ngOnInit() {
  }

}
...