Не срабатывает декоратор @Input в Angular 7

105
23 ноября 2020, 16:40

Имеются компоненты: родительский container и дочерние add-group и group (экземпляр динамического компонента), являющиеся соседями. В add-group есть инпут, из которого получаем значение-название группы, и кнопка добавить группу, запускающая отрисовку компонента group. Задача в том, чтобы название группы, которая только что создалась, возникало в самой группе в заданном месте. Я пробовала передать данные инпута через @Output из add-group в container вместе с созданием экземпляра group. Это получилось. Но при попытке передать данные из container в group через @Input, нормально все работает только если установить один единственный статический экземпляр компонента group и передавать ему название группы. В других случаях декоратор не срабатывает. Пробовала использовать сервисы, но до конца так и не разобралась (я новичок в ангуляре). Подскажите возможные варианты решения c сервисами или без них. Код компонента container, ts:

 export class ContainerComponent {
 @ViewChild(AddDirective) appAdd: AddDirective;
  public title;
  constructor(private componentFactoryResolver: ComponentFactoryResolver) {}
  addNewGroup(title) {
    console.log(title);
    this.title = title;
    const componentFactory = this.componentFactoryResolver.resolveComponentFactory(GroupComponent);
    const viewContainerRef = this.appAdd.viewContainerRef;
    const componentRef = viewContainerRef.createComponent(componentFactory);
  }
  removeGroup() {
    const viewContainerRef = this.appAdd.viewContainerRef;
    viewContainerRef.clear();
  }
}

html:

<div class="container">
  <div class="content"> 
    <app-group [title] = "title" *appAdd></app-group>
    <app-add-group (onAdd)= "addNewGroup($event)"></app-add-group>
    <button (click)="removeGroup()">Remove</button> 
    <div class="card-popup-holder"></div>
  </div>
</div>

Компонент add-group, ts:

@Component({
  selector: 'app-add-group',
  templateUrl: './add-group.component.html',
  styleUrls: ['./add-group.component.scss']
})
export class AddGroupComponent {
  @Output() onAdd: EventEmitter<any> = new EventEmitter();
  public groupName: string;
  isClicked: boolean = false;
  constructor() {}
  toggle() {
    this.isClicked = !this.isClicked;
  }
  calculateClasses() {
    return {
      'add-group': true,
      'add-group-edit': this.isClicked
    }
  }
  addGroup(groupName: string) {
    if(!groupName){
      groupName = "Group title";
    }
    this.groupName = groupName;
    console.log(groupName);
    this.onAdd.emit(groupName);
    console.log("New group created!");
  }
}

html:

<div [ngClass]="calculateClasses()"> 
  <button class="add-group-button" (click) ="toggle()">+ Add another group</button>
  <form action="#">
    <div class="add-group-description">
      <input type="text" placeholder="Enter a list title..." id="input_form" #groupTitle>
      <div class="btn-holder">
        <button class="btn" 
        (click) = "addGroup(groupTitle.value); 
        groupTitle.value= '';">
          Add group
        </button>
        <button class="btn btn-remove-group" (click) ="toggle()">Cancel</button>
      </div>
    </div>
  </form>
</div>

Компонент group, ts:

@Component({
  selector: 'app-group',
  templateUrl: './group.component.html',
  styleUrls: ['./group.component.scss']
})
export class GroupComponent {
  @Input() title;
}

html:

<div class="group">
  <div class="group-header">
    <strong class="title">{{title}}</strong>
    <button class="btn btn-remove" (click)="removeGroup(group.groupTitle)">
      <i class="fa fa-times" aria-hidden="true"></i>
    </button>
  </div>
  <div class="card-holder"></div>
  <div class="group-footer" (click)="addCard()">
    <button class="add-card">+ Add card...</button>
  </div>  
</div>
Answer 1

Действительно, по примеру @overthesanity, дополнила метод addNewGroup в containerComponent.ts строкой

componentRef.instance.title = this.title

и все заработало, названия групп нормально добавляются. Конечный код метода тогда выглядит так:

addNewGroup(title) {
    console.log(title);
    this.title = title;
    const componentFactory = this.componentFactoryResolver.resolveComponentFactory(GroupComponent);
    const viewContainerRef = this.appAdd.viewContainerRef;
    const componentRef = viewContainerRef.createComponent(componentFactory);
    componentRef.instance.title = this.title;
  }

Все остальное без изменений.

READ ALSO
Сортировка вложенных массивов

Сортировка вложенных массивов

Необходимо отсортировать массивы по числовому показателю в последнем индексе каждого массиваТо есть, в массиве mass, в коде ниже, mass[2] должен...

110
Синтаксис замыканий в JS

Синтаксис замыканий в JS

Первый раз столкнувшись с замыканиями и не зная, что это такое, пробовал синтаксически понять, что происходит в коде вида: (function(){})()Известно,...

105
непонятно поведение prototype

непонятно поведение prototype

почему код срабатывает лишь в третьем случае

119