简体   繁体   English

将右元素的数据从ngfor循环传递给子组件

[英]Pass the right element's data from ngfor loop to the child component

Im looking to inject the data from a ngfor loop on the parent component into a child component. 我希望将父组件上的ngfor循环中的数据注入子组件。 This child component is supposed to render a modal with the data of the right element in the parent's ngfor loop, when I click on the respective child component template's render on the parent component template (code below shows the html tag of the child's template on the parent's template). 当我在父组件模板上单击相应的子组件模板的渲染时,此子组件应该使用父组件的ngfor循环中的右元素的数据呈现模态(下面的代码显示了子组件模板上的html标签)父母的模板)。

So far the @input() saleItem: SaleItem; 到目前为止@input() saleItem: SaleItem; property on the child component's modle only takes in data of the first element in the array on the parent component's template, no matter which 'sale item' I click on the parent component's template. 子组件的模型上的属性只接收父组件模板上数组中第一个元素的数据,无论哪个'销售项'我点击父组件的模板。 How can I achieve the desired behaviour of each modal render containing the data of the right element in the ngfor Loop? 如何在ngfor循环中实现包含正确元素数据的每个模态渲染的所需行为?

Already tried Using on changes on the child component. 已经尝试使用子组件上的更改。 This is not working and I assume because the reference of the array in the ngFor loop doesn't actually change. 这不起作用,我假设因为ngFor循环中数组的引用实际上没有改变。

EDIT 编辑

So i did a little digging in the dev tools and this is a snap shot from the Elements tab in chrome. 所以我在开发工具中进行了一些挖掘,这是从chrome中的Elements选项卡中快速拍摄的。 元素选项卡快照 This shows that the data is actually being passed down into the separately rendered child component's template and showing on the modals, but when i click anywhere on the parent components template, only the modal with the first elements data gets triggered. 这表明数据实际上是传递给单独渲染的子组件的模板并显示在模态上,但是当我单击父组件模板上的任何位置时,只会触发具有第一个元素数据的模态。 How do I get the right modal to fire when I click on the dom element on the parent components template that is supposed to fire the modal as shown in the code supplied? 当我点击应该触发模式的父组件模板上的dom元素时,如何获得正确的模式? Parent component model 父组件模型

import { SaleItemsServices } from './../Services/saleItem-service.service';
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-sales-page',
  templateUrl: './sales-page.component.html',
  styleUrls: ['./sales-page.component.scss']
})
export class SalesPageComponent implements OnInit {
  // other inits
  saleItems: any = [];

  imageUrl: String = this.saleItemsService.getItemImageURI();
  constructor(private saleItemsService: SaleItemsServices) {}

  ngOnInit() {
    console.log('im here');
    this.populateSaleItems();
  }
  populateSaleItems() {
    this.saleItemsService.getSalesItems().subscribe(
      data => {
        console.log('data available');
        this.saleItems = data;
        console.log(this.saleItems);
      },
      err => {
        console.log('there was an error fetching the data');
      },
      () => {
        console.log('done loading sale item data');
      }
    );
    console.log('sale items received are as such' + this.saleItems);
  }
}

Parent component template 父组件模板

<div id="backGroundImage">
  <div id="salesPageContainer">
    <div id="saleItemsContainer">
      <p id="banner">This is where the banner will come</p>
      <div
        *ngFor="let saleItem of saleItems"
        id="itemContainer"
        data-toggle="modal"
        data-target="#modalID"
      >
        <app-saleitem-modal [saleItem]="saleItem"></app-saleitem-modal>
        <img [src]="imageUrl + saleItem.imageID" alt="" id="itemImage" />
        <p id="itemName">{{ saleItem.itemName }}</p>
        <p id="itemPrice">{{ saleItem.itemPrice }}</p>
      </div>
    </div>
  </div>
</div>

Child component model 子组件模型

import { SaleItem } from './../../models/saleitem';
import {
  Component,
  OnInit,
  Input,
  OnChanges,
  SimpleChanges
} from '@angular/core';
import { SaleItemsServices } from '../../Services/saleItem-service.service';

@Component({
  selector: 'app-saleitem-modal',
  templateUrl: './saleitem-modal.component.html',
  styleUrls: ['./saleitem-modal.component.scss']
})
export class SaleitemModalComponent implements OnInit, OnChanges {
  @Input() saleItem: SaleItem;
  imageUrl: String = this.saleItemsService.getItemImageURI();

  constructor(private saleItemsService: SaleItemsServices) {}
  ngOnChanges(changes: SimpleChanges) {
    if (changes.saleItem) {
      console.log(
        'the previous value of sale items is' +
          JSON.stringify(changes.saleItem.previousValue)
      );
      console.log(
        'the new value of sale items is ' +
          JSON.stringify(changes.saleItem.currentValue)
      );
    }
  }
  ngOnInit() {
    console.log(this.saleItem);
  }
}

Child component template 儿童组件模板

<div class="modal fade" id="modalID">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h3 id="saleItemName">{{ saleItem.itemName }}</h3>
      </div>
      <div class="modal-body">
        <img
          [src]="imageUrl + saleItem.imageID"
          alt=""
          id="saleItemModalImage"
        />
        <p id="itemWeight">{{ saleItem.itemWeight }}</p>
        <p id="itemPrice">{{ saleItem.itemPrice }}</p>
        <p id="itemCompany">{{ saleItem.itemCompany }}</p>
        <p id="itemCategory">{{ saleItem.itemCategory }}</p>
        <!-- Body here -->
        <div class="modal-footer">
          <div class="col-6">
            <!-- Buttons here -->
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

So I added a function that takes each sale item and assigns it manually to the child components sale item variable, when the image of a particular sale item element is clicked on the parent components template. 因此,当在父组件模板上单击特定销售项目元素的图像时,我添加了一个功能,该功能获取每个销售项目并手动将其分配给子组件销售项目变量。

parent component template 父组件模板


  <div id="salesPageContainer">
    <div id="saleItemsContainer">
      <p id="banner">This is where the banner will come</p>
      <div *ngFor="let saleItem of saleItems" id="itemContainer">
        <img
          [src]="imageUrl + saleItem.imageID"
          alt=""
          id="itemImage"
          (click)="passSaleItem(saleItem)"
          data-toggle="modal"
          data-target="#modalID"
        />
        <app-saleitem-modal [saleItem]="saleItemToPass"></app-saleitem-modal>
        <p id="itemName">{{ saleItem.itemName }}</p>
        <p id="itemPrice">{{ saleItem.itemPrice }}</p>
      </div>
    </div>
  </div>
</div>

parent components model addition 父组件模型添加

passSaleItem(saleItem: SaleItem) {
    this.saleitemModal.saleItem = saleItem;
  }

The modals still get rendered each time anew for each component which is a bit of a drag. 每次为每个组件重新创建模态时仍然会进行渲染,这有点拖累。 Ideally I would have liked for the Modal to be rendered once and the data pushed to it for each item when the image was clicked. 理想情况下,我希望Modal可以渲染一次,并且在单击图像时将数据推送到每个项目。 This gave cannot read property of undefined error as the @Input() saleItem on the child component model was not getting initialized with any values when angular initialized the components. 这使得cannot read property of undefined错误的cannot read property of undefined因为当角度初始化组件时,子组件模型上的@Input() saleItem未使用任何值进行初始化。

Hence I'm currently okay with the solution I have found, albeit with a potential question mark on performance down the line when the application scales. 因此,我现在可以使用我找到的解决方案,尽管在应用程序扩展时可能会出现性能问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM