Angular - ngFor displays all elements in one column

In my angular project I am using ngFor

to display data in a table and for some reason they all appear in the first column. EDIT - this works, but now I'm having problems with mine ngSwitch

. I am getting an error pto-row-edit

saying that it cannot communicate with 'pto' as it is not a known property of 'tr'. I am trying to do this so that the data is displayed in a grid using row-display.component

and then whenever a row is selected, display instead row-edit.component

.

Here's where I call mine row-edit.component

:

<table class="table table-striped table-bordered" *ngIf="empInfo && empInfo.length > selectedEmployee">
  <thead>
    <tr>
      <th>Date</th>
      <th>Full/Half</th>
      <th>Hours</th>
      <th>Scheduled?</th>
      <th>Notes</th>
      <th>In P/R?</th>
    </tr>
  </thead>  
  <tbody>
    <ng-container *ngFor="let pto of (ptoData | currentEmployee:empInfo[selectedEmployee].EmpKey)">
      <ng-container [ngSwitch]="isRowSelected()">
        <ng-container *ngSwitchCase="false">
          <tr pto-row-display [pto]="pto" *ngIf="pto.type === selectedType"></tr>
        </ng-container>
        <ng-container *ngSwitchCase="true">
          <tr pto-row-edit [pto]="pto" [rowSelected]="rowSelected" *ngIf="pto.type === selectedType"></tr>
        </ng-container>
    </ng-container>
   </ng-container>
  </tbody>
</table>

      

here my row-edit.component.ts

:

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

import { PTOData } from './pto-data';

@Component({
    selector: '[pto-row-edit]',
    templateUrl: `./row-edit.component.html`,
    styleUrls: ['./row-edit.component.css']
})

export class RowEditComponent {
    @Input() pto: PTOData[];
}

      

and here my row-edit.component.html

:

<td><input class='form-control' type="text" id="ptoDate" [ngModel]="pto.date | date: 'MM/dd/y'" (ngModelChange)="pto.date=$event" name="ptoDate" /></td>
<td>
  <select class="form-control" id="ptoFullHalf" [(ngModel)]="pto.fullhalf" name="ptoFullHalf">
    <option value="full">Full</option>
    <option value="AM">AM</option>
    <option value="PM">PM</option>
    <option value="(full)">(Full)</option>
    <option value="(half)">(Half)</option>
  </select>
</td>
<td>
  <select class="form-control" id="ptoHours" [(ngModel)]="pto.hours" name="ptoHours">
    <option value="4">4</option>
    <option value="8">8</option>
    <option value="-4">-4</option>
    <option value="-8">-8</option>
  </select>
</td>
<td>
  <select class="form-control" id="ptoScheduled" [(ngModel)]="pto.scheduled" name="ptoScheduled">
    <option value=""></option>
    <option value="advanced">Advanced</option>
    <option value="scheduled">Scheduled</option>
    <option value="unscheduled">Unscheduled</option>
  </select>
</td>
<td><input class='form-control' type="text" id="ptoNotes" [(ngModel)]="pto.notes" name="ptoNotes" /></td>
<td>
  <input class="form-check-input" type="checkbox" id="ptoinPR" [(ngModel)]="pto.inPR" name="ptoinPR" />
</td>

      

I really feel like this should work, and I'm not entirely sure why it doesn't.

+3


source to share


1 answer


In table

elements, you cannot place a custom element in it. If you add a custom element to an element table

, they will be considered invalid html and that element will be thrown out of the tag table

.

In this case, I recommend that you create a component selector attribute and then move the condition pto.type === selectedType

to CustomPipe ngFor

so we can get rid of ng-container

. Maybe you can extend currentEmployee

Pipe with pto.type === selectedType

(this check). Subsequently directly place pto-row-display

on tr

as in the attribute.

selector: '[pto-row-display]'

      

And then use it as an attribute



<table class="table table-striped table-bordered" *ngIf="empInfo && empInfo.length > selectedEmployee">
  <thead>
   <tr>
    <th>Date</th>
    <th>Full/Half</th>
    <th>Hours</th>
    <th>Scheduled?</th>
    <th>Notes</th>
    <th>In P/R?</th>
   </tr>
  </thead>
  <tbody>
   <tr 
    *ngFor="let pto of (ptoData | currentEmployee:empInfo[selectedEmployee].EmpKey):selectedType" 
    pto-row-display [pto]="pto">
    </tr>
  </tbody>
</table>

      

currentEmployee Pipe

import { Pipe, PipeTransform } from '@angular/core';

import { PTOData } from './pto-data';

@Pipe({ name: 'currentEmployee' })
export class CurrentEmployee implements PipeTransform {
    transform(allData: PTOData[], key: number, selectedType: any) {
        return (allData ? allData.filter(emp => emp.EmpKey == key && emp.type === selectedType) : []);
    }
}

      

+2


source







All Articles