sosick
sosick

Reputation: 632

Angular 4 - make component more reusable

I want to make my component more reusable. In the component I'm binding two values with ngModel: elem.key and elem.value. The problem is that wherever I want to use this component, the element has to have key and value properties, for example some data from Api might have name, and nickname etc. For now I can use my component repeatedly, but only if the values of object are key and value. My code:

html:

<button (click)="addNew()">Add</button>
        <div *ngFor="let elem of elements">
          <text-input [(ngModel)]="elem.key" type="text"></text-input>
          <text-input [(ngModel)]="elem.value" type="text"></text-input>
        </div>

ts:

@Input() elements: any[];

  addNew() {
    this.elements.push({
      key: '',
      value: ''
      });
    }

If I use my component in another:

        <input-key-value [elements]="values">

It works fine if I only need to add to values array {key: '', value: ''} But sometimes I want to add for example {name: '', nickname: ''}, cause data in this format must be sent to the server.

I tried add another Input name inputs, {key: 'name', value: 'name'} And in html:

      <text-input [(ngModel)]="elem[inputs.key]" type="text"></text-input>
      <text-input [(ngModel)]="elem.[inputs.value]" type="text"></text-input>

But this is again pushing wrong data to my main array.

Upvotes: 2

Views: 487

Answers (2)

lloydaf
lloydaf

Reputation: 605

This worked for me.

input-key-value template:

<div *ngFor="let elem of elements">
  <div *ngFor="let prop of keys(elem)" >
    <text-input type="text" [(ngModel)]="elem[prop]"></text-input>
  </div>
</div>

input-key-value ts:

keys(element) {
    return Object.keys(element);
}

Depending on how many properties your object has, it renders as much text boxes. Hope this will help.

Upvotes: 4

Venkatesh Konatham
Venkatesh Konatham

Reputation: 828

In your add new function you might need to do like below

@Input() elements: any[];
@Input() elementKey: string = 'key';
@Input() elementValue: string = 'value';
addNewe() {
    const element = {};
    element[this.elementKey] = '';
    element[this.elementValue] = '';
    this.elements.push(element);
}

and in your view, you should do like below

<button (click)="addNew()">Add</button>
<div *ngFor="let elem of elements">
    <text-input [(ngModel)]="elem[elementKey]"
        type="text"></text-input>
    <text-input [(ngModel)]="elem[elementValue]"
        type="text"></text-input>
</div>

you might need to pass element key and element values when when you are using this component

when you are using your component. If you have to pass key and value like below, based on example that you have provided in comment {name: '', nickname: ''}

<input-key-value [elements]="values" [elementKey]='name' [elementValue]='nickname'>

If you are passing elements like {key: '', value: ''} then there is no requirment to pass element key and element value inputs. you can directly use it

<input-key-value [elements]="values">

Upvotes: 2

Related Questions