如何在具有输入的子组件中访问父组件的for循环?

时间:2019-01-10 22:55:33

标签: javascript arrays angular

所以我坚持了这一点。我试图让父组件与子组件进行对话或集成。 这是父组件,基本上,如果用户要添加更多或按下按钮添加更多,则该组件主要具有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 :(得分:2)

让组件相互区分的标准方法是输入输出:

例如,您可以使用@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达成相同的目标,但我建议您使用上述方式

希望它能提供帮助

答案 1 :(得分:2)

下面的代码和示例将通过使用@Input()@Output()指令来演示数据如何从父->子->父流。

Working Example Here

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

}

答案 2 :(得分:0)

我不会特别这样做。如果孩子必须了解父母,那么应该调整您的建筑