কৌণিক 2 - এর পরিবর্তে সংকলনগুলি ব্যবহার করে এনজিএফ


190

...উদাহরণ স্বরূপ...

<div class="month" *ngFor="#item of myCollection; #i = index">
...
</div>

এর মতো কিছু করা সম্ভব ...

<div class="month" *ngFor="#item of 10; #i = index">
...
</div>

... একটি মার্জিত নয় এমন সমাধানের কাছে আবেদন না করে যেমন:

<div class="month" *ngFor="#item of ['dummy','dummy','dummy','dummy','dummy',
'dummy','dummy','dummy']; #i = index">
...
</div>

?


8
আমি একই সমস্যা আছে। সত্যিই বিপর্যস্ত এক কৌণিক 2. দিয়ে এত সহজ জিনিস ব্যবহার করতে পারবেন না
albanx

1
হতে পারে এটি সহায়ক হতে পারে: স্ট্যাকওভারফ্লো.com
প্রশ্নগুলি

উত্তর:


195

আপনার উপাদানগুলির মধ্যে, আপনি নীচের বর্ণিত হিসাবে সংখ্যার অ্যারে (ES6) সংজ্ঞায়িত করতে পারেন:

export class SampleComponent {
  constructor() {
    this.numbers = Array(5).fill().map((x,i)=>i); // [0,1,2,3,4]
    this.numbers = Array(5).fill(4); // [4,4,4,4,4]
  }
}

অ্যারে তৈরির জন্য এই লিঙ্কটি দেখুন: জাভাস্ক্রিপ্টে 1..20 থেকে পূর্ণসংখ্যার অ্যারে তৈরির সবচেয়ে নিখুঁত উপায়

তারপরে আপনি এই অ্যারেটির সাথে পুনরাবৃত্তি করতে পারেন ngFor:

@Component({
  template: `
    <ul>
      <li *ngFor="let number of numbers">{{number}}</li>
    </ul>
  `
})
export class SampleComponent {
  (...)
}

বা শীঘ্রই:

@Component({
  template: `
    <ul>
      <li *ngFor="let number of [0,1,2,3,4]">{{number}}</li>
    </ul>
  `
})
export class SampleComponent {
  (...)
}

5
হ্যাঁ, থিয়েরি! এটি আসলে আপনার দোষ নয়, তবে এখনও একই প্রসঙ্গে :( এটি মোটেও মার্জিত নয় But তবে আপনি যেহেতু খুব দক্ষ এ 2 বিকাশকারী, তাই আমি ধরে নিতে পারি যে এর চেয়ে ভাল কোনও সমাধান নেই It's এটি দুঃখজনক!
মার্কো জুনিয়র

আসলে লুপ সিনট্যাক্সে অ্যাঙ্গুলার 2 এ এর ​​জন্য কিছুই নেই। অ্যারে তৈরি করতে জাভাস্ক্রিপ্ট কী সরবরাহ করে তা আপনার লাভ করতে হবে। উদাহরণস্বরূপ: Array(5).fill(4)তৈরি করতে[4,4,4,4,4]
থিয়েরি টেম্পিলার

3
PS: @ দেখুন টীকাটি কৌণিক 2 বিটা 10 এবং তদূর্ধে সরানো হয়েছে।
পারদীপ জৈন

23
Array.fill()কৌণিক 2 টাইপস্ক্রিপ্টে ব্যবহার করে নিম্নলিখিত ত্রুটিটি তৈরি হয় Supplied parameters do not match any signature of call t arget.- অ্যারে.প্রোটোটাইপ.ফিল ডক্স চেক করা, এটি বলছে এটির জন্য 1 টি যুক্তি প্রয়োজন ... বিকাশকারী.মোজিলা.আর
জোশুয়া রাসেল

5
Array(5).fill(1).map((x, i) => i + 1); /*[1,2,3,4,5]*/এটি টিএস
মিশাহবাজম

85

@ ওপ, আপনি আপনার "অ-মার্জিত" সমাধানটির সাথে খুব ভয়ঙ্করভাবে ঘনিষ্ঠ ছিলেন।

কেমন:

<div class="month" *ngFor="let item of [].constructor(10); let i = index"> ... </div>

এখানে আমি Arrayএকটি খালি অ্যারে থেকে নির্মাতা পেয়ে যাচ্ছি : [].constructorকারণ Arrayটেমপ্লেট সিনট্যাক্সের কোনও স্বীকৃত প্রতীক নয়, এবং @ পার্বদীপ-জেনের মতো উপাদান টাইপস্ক্রিপ্ট করতে আমি খুব অলস Array=Arrayবা counter = Arrayতার ৪ র্থ উদাহরণে এসেছি । এবং আমি এটি ছাড়াই কল করছি newকারণ নির্মাণকারীর newবাইরে অ্যারে পাওয়ার জন্য প্রয়োজনীয় নয় Array

Array(30)এবং new Array(30)সমতুল্য।

অ্যারেটি খালি থাকবে, তবে এটি কোনও ব্যাপার নয় কারণ আপনি সত্যই আপনার লুপ iথেকে ব্যবহার করতে চান ;let i = index


11
এটি সেরা উত্তর।
ক্যাগ্রোনিক

এই সমাধানটি পরিবর্তন সনাক্তকরণকে ট্রিগার করে। আমার ধারণা নতুন অ্যারের কারণে।
টোবিয়াস 8১

1
@ টোবিয়াস ৮১, আপনি কি আরও বিস্তারিত বলতে পারবেন? আপনি কি বলছেন যে অ্যাপটি প্রতিবার পরিবর্তন সনাক্তকরণ চালায়, অ্যারেটি পুনরায় তৈরি করার কারণে * এনজিফোর্ডের বিষয়বস্তুগুলি পুনরায় চিত্রিত করা হয়? এটি অবশ্যই লক্ষণীয়। টিএসে রেফারেন্সের জন্য একটি অ্যারে ক্ষেত্র তৈরি করে এটির কাছাকাছি যেতে পারে তাই প্রতিবার পরিবর্তন সনাক্তকরণের সময় একই রকম হয়। তবে এটি অবশ্যই পছন্দসই চেয়ে কম মার্জিত হবে। থিয়েরি টেম্পিলারের নির্বাচিত উত্তরে একই উদাহরণ সনাক্তকরণ সমস্যাটি কি দ্বিতীয় উদাহরণে উপস্থিত? <li *ngFor="let number of [0,1,2,3,4]">{{number}}</li>
jcairney

এই সমস্যার জন্য এটি সেরা সমাধান খুঁজে পাওয়া যায়
খুশ করুন

1
@ টোবিয়াস ৮১, আমি নিশ্চিত করেছি যে পরিবর্তনটি সনাক্তকরণ এনজিফোর্ডের বিষয়বস্তু বারবার পুনরায় তৈরি করবে না তা নিশ্চিত করার জন্য, আমি উদাহরণস্বরূপ এনজিওর জন্য উদাহরণ হিসাবে একটি শিশু হিসাবে তৈরি করেছি এমন একটি উপাদানটির কনস্ট্রাক্টরের ভিতরে একটি মুদ্রণ বিবৃতি রেখে। আমি প্রতিটি পরিবর্তন সনাক্তকরণ পুনরাবৃত্তিতে উপাদানগুলি পুনরায় তৈরি করা দেখতে পাচ্ছি না, তাই আমি মনে করি না যে আসলেই কোনও সমস্যা আছে (কমপক্ষে কৌনিক 8 এ)।
jcairney

83

এনজিফোর্ডের পরিবর্তে সংগ্রহগুলি ব্যবহারের জন্য এখনও কোনও পদ্ধতি নেই, এই মুহুর্তে, * এনজিফোর্ড কেবলমাত্র প্যারামিটার হিসাবে একটি সংগ্রহ গ্রহণ করে, তবে আপনি নিম্নলিখিত পদ্ধতিগুলি দ্বারা এটি করতে পারেন:

পাইপ ব্যবহার

pipe.ts

import {Pipe, PipeTransform} from 'angular2/core';

@Pipe({name: 'demoNumber'})
export class DemoNumber implements PipeTransform {
  transform(value, args:string[]) : any {
    let res = [];
    for (let i = 0; i < value; i++) {
        res.push(i);
      }
      return res;
  }
}


<ul>
  <li>Method First Using PIPE</li>
  <li *ngFor='let key of 5 | demoNumber'>
    {{key}}
  </li>
</ul>

সরাসরি এইচটিএমএলে নম্বর অ্যারে ব্যবহার করা (দেখুন)

<ul>
  <li>Method Second</li>
  <li *ngFor='let key of  [1,2]'>
    {{key}}
  </li>
</ul>

বিভক্ত পদ্ধতি ব্যবহার করে

<ul>
  <li>Method Third</li>
  <li *ngFor='let loop2 of "0123".split("")'>{{loop2}}</li>
</ul>

উপাদানটিতে নতুন অ্যারে তৈরি করা Using

<ul>
  <li>Method Fourth</li>
  <li *ngFor='let loop3 of counter(5) ;let i= index'>{{i}}</li>
</ul>

export class AppComponent {
  demoNumber = 5 ;

  counter = Array;

  numberReturn(length){
    return new Array(length);
  }
}

ওয়ার্কিং ডেমো


4
আপনি থিয়েরিস উত্তরে দেখানোর Array.fill()পরিবর্তে অ্যারে তৈরির জন্য পদ্ধতিটিও ব্যবহার করতে পারেন res.push()
গন্টার জ্যাচবাউয়ার

হ্যাঁ আমি পারব তবে এতে কোন ভুল আছে pushকি? মানে উভয় পদ্ধতি সঠিক তবে এখনও যদি কোনও ভিন্ন হয়। তাদের মধ্যে.
পারদীপ জৈন

3
না, এখনও একটি দুর্দান্ত সমাধান +1। আমি কেবল Array.fill()ধাক্কা ব্যবহার করে লুপের চেয়ে আরও মার্জিত দেখতে পাই এবং এটি সম্ভবত আরও দক্ষ।
গন্টার জ্যাচবাউয়ার

1
আমি counter = Arrayখুব স্মার্ট;) সহ এই সমাধানটি পছন্দ করি
ভেরি

11

আমি উপাদানগুলির সরল পুনরাবৃত্তির জন্য একটি অ্যারের বরাদ্দ করার ধারণাটি সহ্য করতে পারি না, তাই আমি একটি কাঠামোগত নির্দেশনা লিখেছি। সরল আকারে, এটি সূচকে টেমপ্লেটে উপলব্ধ করে না, এটি দেখতে এটির মতো দেখাচ্ছে:

import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';

@Directive({ selector: '[biRepeat]' })
export class RepeatDirective {

  constructor( private templateRef: TemplateRef<any>,
             private viewContainer: ViewContainerRef) { }

  @Input('biRepeat') set count(c:number) {
    this.viewContainer.clear();
    for(var i=0;i<c;i++) {
      this.viewContainer.createEmbeddedView(this.templateRef);
    }
  }
}

http://plnkr.co/edit/bzoNuL7w5Ub0H5MdYyFR?p=preview


আমি সম্মত হচ্ছি অ্যারে পদ্ধতিরটি কুৎসিত, তবে এটি আমার কাছে অকাল অপ্টিমাইজেশনের মতো মনে হয়।
আলুয়ান হাদাদ

3
অবশ্যই, তবে একটি নির্দেশিকা লেখার একটি অনুশীলনও। অন্যদিকে এটি পাইপের চেয়ে দীর্ঘ নয়, এটি দ্বিতীয় জ্ঞানের পদ্ধতি হবে।
pdudits

এটি একটি ভাল বিষয়, কাস্টম কাঠামোগত দিকনির্দেশনাগুলির ধারণার সাথে আপনার কিছু পাওয়ার অনেক সুযোগ নেই।
আলুয়ান হাদাদ

: - নিস এক @pdudits এখনও সর্বশেষ সংস্করণ সঙ্গে কাজ করে plnkr.co/edit/8wJtkpzre3cBNokHcDL7?p=preview [আপনার plnkr আপডেট করার জন্য বিনা দ্বিধায়]
যেমন AT

5

আমি এঙ্গুলার 5.2.6 এবং টাইপস্ক্রিপ্ট 2.6.2 ব্যবহার করে এটির মতো সমাধান করেছি:

class Range implements Iterable<number> {
    constructor(
        public readonly low: number,
        public readonly high: number,
        public readonly step: number = 1
    ) {
    }

    *[Symbol.iterator]() {
        for (let x = this.low; x <= this.high; x += this.step) {
            yield x;
        }
    }
}

function range(low: number, high: number) {
    return new Range(low, high);
}

এটি এর মতো কোনও অংশে ব্যবহার করা যেতে পারে:

@Component({
    template: `<div *ngFor="let i of r">{{ i }}</div>`
})
class RangeTestComponent {
    public r = range(10, 20);
}

ত্রুটি পরীক্ষা করা এবং সংক্ষিপ্ততার উদ্দেশ্যে উদ্দেশ্য বাদ দেওয়া জোর (উদাহরণস্বরূপ পদক্ষেপ নেতিবাচক হলে কী হয়)।


2
এইচটিএমএল-তে কোনও উপায় আছে <div *ngfor="let i of 4, i++"></div>কি না
নিথিলা শানমুগানন্তন

5

আপনি এটি ব্যবহার করতে পারেন

export class SampleComponent {
   numbers:Array<any> = [];
   constructor() {
      this.numbers = Array.from({length:10},(v,k)=>k+1);
   }
}

এইচটিএমএল

<p *ngFor="let i of numbers">
   {{i}}
</p>

4

আপনি লোডাশ ব্যবহার করতে পারেন:

@Component({
  selector: 'board',
  template: `
<div *ngFor="let i of range">
{{i}}
</div>
`,
  styleUrls: ['./board.component.css']
})
export class AppComponent implements OnInit {
  range = _.range(8);
}

আমি কোড পরীক্ষা করিনি তবে এটি কাজ করা উচিত।


এইচটিএমএল-তে কোনও উপায় আছে <div *ngfor="let i of 4, i++"></div>কি না
নিথিলা শানমুগানন্তন

আপনার যদি প্রয়োজন হয় iবা একটি কোডে সূচি থাকে তবে আপনি করতে পারেন*ngFor="let i of range; let i = index"
অ্যালেক্স পো


2

যেহেতু আর্গুমেন্ট ছাড়াই পূরণ () পদ্ধতিটি (গৃহীত উত্তরে উল্লিখিত) ত্রুটি ছুঁড়েছে, তাই আমি এর মতো কিছু প্রস্তাব করব (আমার জন্য কাজ করে, কৌণিক .0.০.৪, টাইপসক্রিপ্ট ৩.১..6)

<div class="month" *ngFor="let item of items">
...
</div>

উপাদান কোডে:

this.items = Array.from({length: 10}, (v, k) => k + 1);

1
<div *ngFor="let number of [].constructor(myCollection)">
    <div>
        Hello World
    </div>
</div>

এটি আমার সংগ্রহের পরিমাণের জন্য পুনরাবৃত্তি করার একটি দুর্দান্ত এবং দ্রুত উপায়।

সুতরাং আমার সংগ্রহটি যদি 5 হয়, হ্যালো ওয়ার্ল্ড 5 বার পুনরাবৃত্তি হবে।


1

সূচক সহ কাস্টম স্ট্রাকচারাল দিকনির্দেশনা ব্যবহার:

কৌণিক ডকুমেন্টেশন অনুযায়ী:

createEmbeddedView একটি এম্বেড করা ভিউ ইনস্ট্যান্ট করে এবং এই ধারকটিতে এটি সন্নিবেশ করায়।

abstract createEmbeddedView(templateRef: TemplateRef, context?: C, index?: number): EmbeddedViewRef

Param          Type           Description
templateRef    TemplateRef    the HTML template that defines the view.
context        C              optional. Default is undefined.
index          number         the 0-based index at which to insert the new view into this container. If not specified, appends the new view as the last entry.

যখন কৌণিক ক্রেডিট এম্বেডভিউ কল করে টেমপ্লেট তৈরি করে এটি অভ্যন্তরে ব্যবহৃত প্রসঙ্গটিও পাস করতে পারে ng-template

প্রসঙ্গ optionচ্ছিক প্যারামিটার ব্যবহার করে, আপনি এটি উপাদানটিতে ব্যবহার করতে পারেন, টেমপ্লেটের মধ্যে যেমন আপনি * এনজিফোয়ার সাথে করতে চান তেমন এটি বের করে নিতে।

app.component.html:

<p *for="number; let i=index; let c=length; let f=first; let l=last; let e=even; let o=odd">
  item : {{i}} / {{c}}
  <b>
    {{f ? "First,": ""}}
    {{l? "Last,": ""}}
    {{e? "Even." : ""}}
    {{o? "Odd." : ""}}
  </b>
</p>

for.directive.ts:

import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';

class Context {
  constructor(public index: number, public length: number) { }
  get even(): boolean { return this.index % 2 === 0; }
  get odd(): boolean { return this.index % 2 === 1; }
  get first(): boolean { return this.index === 0; }
  get last(): boolean { return this.index === this.length - 1; }
}

@Directive({
  selector: '[for]'
})
export class ForDirective {
  constructor(private templateRef: TemplateRef<any>, private viewContainer: ViewContainerRef) { }

  @Input('for') set loop(num: number) {
    for (var i = 0; i < num; i++)
      this.viewContainer.createEmbeddedView(this.templateRef, new Context(i, num));
  }
}

0

আপনি যদি একটি বোতামে ক্লিক করার পরে কোনও অ্যারের আকারকে গতিশীলভাবে বাড়িয়ে তুলতে চান তবে দয়া করে আমার গতিশীল সমাধানটি সন্ধান করুন (আমি এই প্রশ্নটিতে এইভাবে এসেছি)।

প্রয়োজনীয় ভেরিয়েবল বরাদ্দ:

  array = [1];
  arraySize: number;

অ্যারেতে একটি উপাদান যুক্ত করে এমন ফাংশনটি ঘোষণা করুন:

increaseArrayElement() {
   this.arraySize = this.array[this.array.length - 1 ];
   this.arraySize += 1;
   this.array.push(this.arraySize);
   console.log(this.arraySize);
}

HTML এ ফাংশন ডাকা

  <button md-button (click)="increaseArrayElement()" >
      Add element to array
  </button>

এনজিফোর্ডের সাথে অ্যারের মাধ্যমে ইটারেট করুন:

<div *ngFor="let i of array" >
  iterateThroughArray: {{ i }}
</div>

এইচটিএমএল-তে কোনও উপায় আছে <div *ngfor="let i of 4, i++"></div>কি না
নিথিলা শানমুগানন্তন

আপনি একটি অ্যারের পুনরুক্তি উপর আছে। আপনার যদি স্কেলারের প্রয়োজন হয় তবে আপনি সঠিক আকারের সাথে একটি অ্যারের উপরে পুনরাবৃত্তি করতে পারেন এবং এটির পাশাপাশি একটি স্কেলার ইনস্ট্যান্ট করতে পারেন: * এনজিফোর্স = "অ্যারের আইটেম দিন; আই = সূচক দিন"
জান ক্লেম্যানস স্টফ্রেজেন

0

একটি সহজ উপায় যা আমি চেষ্টা করেছি

আপনি আপনার উপাদান ফাইলে একটি অ্যারেও তৈরি করতে পারেন এবং অ্যারে হিসাবে ফিরে এসে আপনি * এনজিফোর্ড নির্দেশের সাথে এটি কল করতে পারেন call

এটার মতো কিছু ....

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

@Component({
  selector: 'app-morning',
  templateUrl: './morning.component.html',
  styleUrls: ['./morning.component.css']
})
export class MorningComponent implements OnInit {

  arr = [];
  i: number = 0;
  arra() {
    for (this.i = 0; this.i < 20; this.i++) {
      this.arr[this.i]=this.i;
    }
    return this.arr;
  }

  constructor() { }

  ngOnInit() {
  }

}

আর এই ফাংশন আপনার HTML টেম্পলেট ফাইল ব্যবহার করা যেতে পারে

<p *ngFor="let a of arra(); let i= index">
value:{{a}} position:{{i}}
</p>

2
হিসাবে HTML এ কোন উপায়ে আছে হয় <div *ngfor="let i of 4, i++"></div>হতে পারে
Nithila Shanmugananthan

0

আমার সমাধান:

export class DashboardManagementComponent implements OnInit {
  _cols = 5;
  _rows = 10;
  constructor() { }

  ngOnInit() {
  }

  get cols() {
    return Array(this._cols).fill(null).map((el, index) => index);
  }
  get rows() {
    return Array(this._rows).fill(null).map((el, index) => index);
  }

HTML এ:

<div class="charts-setup">
  <div class="col" *ngFor="let col of cols; let colIdx = index">
    <div class="row" *ngFor="let row of rows; let rowIdx = index">
      Col: {{colIdx}}, row: {{rowIdx}}
    </div>
  </div>
</div>

এটি প্রতিটি লাভে একটি নতুন অ্যারে তৈরি করে। ওভারহেড তৈরি করতে পারে
রিমকো ভিলারিম্যান
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.