简体   繁体   中英

How can I pass pre generated array to component in template in angular?

I have an items array and loop it into a component. Display items props separately:

Items Array

const items = [
    {
        'name': 'item1', 
        'prop1': 'text1', 
        'prop2': 'text2',
        'boolval': true
    },
    {
        'name': 'item2', 
        'prop1': 'text1', 
        'prop2': 'text2',
        'boolval': false
    },
    {
        'name': 'item3', 
        'prop1': 'text1', 
        'prop2': 'text2',
        'boolval': true
    }];

Component

<div class="all-items">
    <app-items [item]="items"></app-items>
</div>

<div class="specific-items">
    <app-items [item]="items"></app-items>
</div>

HTML

<div class="title">List</div>
<p>Name: {{item.name}}</p>
<p>Prop1: {{item.prop1}}</p>
<p>Prop2: {{item.prop2}}</p>

I want to display all items under the .all-items div, but display item which has boolval=true prop under the .specific-items div. Generated HTML for all-items looks like the following:

<div class="all-items">
    <app-items>
        <div class="title">List</div>
        <p>Name: item1</p>
        <p>Prop1: text1</p>
        <p>Prop2: text2</p>
    </app-items>
    <app-items>
        <div class="title">List</div>
        <p>Name: item2</p>
        <p>Prop1: text1</p>
        <p>Prop2: text2</p>
    </app-items>
    <app-items>
        <div class="title">List</div>
        <p>Name: item3</p>
        <p>Prop1: text1</p>
        <p>Prop2: text2</p>
    </app-items>
</div>

I want to display specific items like this;

<div class="specific-items">
    <app-items [item]="items.filter(x => x.boolval=== true)"></app-items>
</div>

<div class="specific-items">
    <app-items>
        <div class="title">List</div>
        <p>Name: item1</p>
        <p>Prop1: text1</p>
        <p>Prop2: text2</p>

        <p>Name: item3</p>
        <p>Prop1: text1</p>
        <p>Prop2: text2</p>
    </app-items>
</div>

How can I generate a specific array in template like this [item]="items.filter(x => x.boolval=== true)" and pass it to component? So I want generate a specific array in template and then send it to component

You can create a pipe to filter the array.

Here is the final solution

app-items.pipe.ts

@Pipe({
  name: 'appItemsFilter'
})
export class AppItemsFilter implements PipeTransform {

  transform(items) {
    return items.filter(x => x.boolval);
  }
}

And you can simply use it as following

<div class="all-items">
  <app-items [items]="items"></app-items>
</div>

<div class="specific-items">
  <app-items [items]="items | appItemsFilter"></app-items>
</div>

Also, this pipe is pure which means angular will not call tranform method unless items array reference change (operations like push , pop won't trigger change detection) So, performance will be a lot better than calling methods from template.

In angular, you can try below-

    <div class="all-items">
    <app-items *ngFor="let item of items;let i= index">
        <div class="title">List</div>
      <ng-container *ngIf="item.boolval">
        <p>Name: {{item?.name}}</p>
        <p>Prop1: {{item?.prop1}}</p>
        <p>Prop2: {{item?.prop2}}</p>
      </ng-container>
    </app-items>
  </div>

Added the code in stackbliz

modified the HTML structure little and added some conditions.

<div class="all-items">
    <app-items [items]="items" case="1"></app-items>
</div>

<div class="specific-items">
    <app-items [items]="items" case="2"></app-items>
</div>

<div class="title">List</div>
<div *ngFor="let item of items">
    <div *ngIf="case == 1 || (case == 2 && item.boolval == true)">
        <p>Name: {{item.name}}</p>
        <p>Prop1: {{item.prop1}}</p>
        <p>Prop2: {{item.prop2}}</p>
    </div>
</div>

you can pass pipe direclty to the array to *ngFor

@Pipe({
 name: 'itemsFilter'
})
export class AppItemsFilter implements PipeTransform {

  transform(items) {
   return items.filter(x => x.boolval);
  }
}

in your html

  <div class="specific-items">
  <app-items>
   <div class="title">List</div>
   <ng-container *ngFor="let item of items | itemsFilter">
      <p>Name: {{item?.name}}</p>
      <p>Prop1: {{item?.prop1}}</p>
      <p>Prop2: {{item?.prop2}}</p>
    <ng-container>
  </app-items>
</div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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