Как получить доступ к циклу for родительского компонента внутри дочернего компонента, который имеет входы? - PullRequest
0 голосов
/ 11 января 2019

Так что я застрял на этом. Я пытаюсь заставить родительский компонент общаться или интегрироваться с дочерним компонентом. Вот родительский компонент, который в основном имеет цикл for, используемый для итерации или генерирования большего количества ссылок, если пользователь хочет добавить больше или нажимает кнопку, чтобы добавить больше.

<div class="section url-wrapper">
    <div *ngFor="let url of urls; let i = index;" class="link input-wrapper">
            <childComponent></childComponent>
      <button class="button bad icon-only" (click)="removeURL(i)">
        <i class="far fa-times"></i>
      </button>
    </div>
  </div>

Родительский компонент должен иметь возможность только регистрировать и отображать выходные данные дочернего компонента.

Это пример дочернего компонента

<div class="section url-wrap">
    <input aria-label="URL Title" placeholder="Title" type="text" [value]="urls[i].title" (ngModel)="urls[i].title" name="url.title.{{ i }}"
        (input)="updateTitle(i, $event.target.value)">

          <input aria-label="URL" placeholder="https://example.com" type="text" [value]="urls[i].url" (ngModel)="urls[i].url" name="url.url.{{ i }}"
          (input)="updateUrl(i, $event.target.value)">   
 </div>

Мне нужна помощь как для разрешения родительскому компоненту регистрировать входные данные дочернего компонента, так и для возможности итерации из цикла for родительского компонента, если это возможно.

Пожалуйста, дайте мне знать, если вам нужна дополнительная информация, такая как файлы компонентов или пояснения

Ответы [ 3 ]

0 голосов
/ 11 января 2019

Приведенный ниже код и пример продемонстрируют, как данные передаются из parent -> child -> parent с использованием директив @Input() и @Output().

Рабочий пример здесь

parent.component.ts

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

@Component({
  selector: 'app-parent',
  template: `
    <div class="section url-wrapper">
      <div *ngFor="let url of urls" class="link input-wrapper">
        <app-child [url]="url" (updateUrl)="onUrlUpdate($event)"></app-child>
      </div>
    </div>
  `
})
export class ParentComponent implements OnInit {
  public urls = [
    {url: "https://example.com", title: "Example1"},
    {url: "https://example.com", title: "Example2"},
    {url: "https://example.com", title: "Example3"},
  ]
  constructor() { }

  ngOnInit() {

  }

  onUrlUpdate($event) {
    // completely overkill, but just used to demonstrate a point
    var url = this.urls.find(_url => {
      // we can see here that the $event.url is actually the same object as the urls[i] that was
      // passed to the child. We do not lose the reference when it is passed to the child or back
      // up to the parent. 
      return $event.url === _url
    });
    if (url) {
      url[$event.prop] = $event.newValue;
    }
    console.log(`Updated URL's "${$event.prop}" property with the value "${$event.newValue}"`);
  }

}

child.component.ts

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

@Component({
  selector: 'app-child',
  template: `
  <div class="section url-wrap">
    <input aria-label="URL Title" placeholder="Title" type="text" [value]="url.title"
        (input)="handleUrlUpdate($event, 'title')"/>

    <input aria-label="URL" placeholder="https://example.com" type="text" [value]="url.url"
        (input)="handleUrlUpdate($event, 'url')"/>   
 </div>
  `,
})
export class ChildComponent implements OnInit {
  @Input() url; // passed in from parent via [url] property on <app-child>
  @Output() updateUrl = new EventEmitter();
  constructor() { }

  ngOnInit() {
    // this.url is now available for the life of the child component (assuming it was passed by the parent)
  }

  handleUrlUpdate($event, propToUpdate) {
    // overkill, but used to demonstrate a point
    this.updateUrl.emit({url: this.url, prop: propToUpdate, newValue: $event.target.value});
  }

}
0 голосов
/ 11 января 2019

Я бы так не поступил именно так. Если дети должны знать о родителях, то ваша архитектура должна быть скорректирована

0 голосов
/ 11 января 2019

Стандартный способ дать компонентам запятнать друг друга - это ввод-вывод:

Вы можете передать значения от родителя детям с помощью @Input, например:

Родительский код:

<childComponent [someInputValue]="hello"></childComponent>

Детский код:

@Input() someInputValue; //this property will be "hello"

и вы можете передавать значения (после срабатывания) от детей к родителю:

Детский код:

  @Output() itemSelectedOutput: EventEmitter<any> = new EventEmitter();

  buttonClicked() {
   this.itemSelectedOutput.emit("clicked");
  }

Родительский код:

    <childComponent [someInputValue]="hello" (itemSelectedOutput)="someParentMethod($event)"></childComponent>

someParentMethod(event: any) {
 console.log(event);
}

Вы можете достичь того же самого с помощью ISubscription, но я предлагаю вам использовать способ выше

Надеюсь, это поможет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...