सवाल कोणीय में वस्तु पर Iterate


मैं कोणीय 2 अल्फा 28 में कुछ चीजें करने की कोशिश कर रहा हूं, और मुझे शब्दकोश और NgFor के साथ कोई समस्या है।

मेरे पास टाइपस्क्रिप्ट में एक इंटरफेस है जो इस तरह दिख रहा है:

interface Dictionary {
    [ index: string ]: string
}

जावास्क्रिप्ट में यह एक ऑब्जेक्ट में अनुवाद करेगा कि डेटा इस तरह दिख सकता है:

myDict={'key1':'value1','key2':'value2'}

मैं इस पर फिर से प्रयास करना चाहता हूं और कोशिश की:

<div *ngFor="(#key, #value) of myDict">{{key}}:{{value}}</div>

लेकिन इसका कोई फायदा नहीं हुआ, इनमें से कोई भी काम नहीं करता है:

<div *ngFor="#value of myDict">{{value}}</div>
<div *ngFor="#value of myDict #key=index">{{key}}:{{value}}</div>

सभी मामलों में मुझे "अप्रत्याशित टोकन" जैसी त्रुटियां मिलती हैं या "यह नहीं मिल पाती है 'iterableDiff' पाइप सहायक ऑब्जेक्ट"

मुझे यहां क्या समझ नहीं आ रहा है? क्या यह अब और संभव नहीं है? (पहला वाक्यविन्यास कोणीय 1.x में काम करता है) या एक ऑब्जेक्ट पर पुनरावृत्ति के लिए वाक्यविन्यास अलग है?


76
2017-07-18 11:30


मूल


एक "शब्दकोश" क्या है? मैंने जावास्क्रिप्ट, कोणीय, या टाइपस्क्रिप्ट संदर्भ में उस शब्द को कभी नहीं देखा या सुना है। Y


जवाब:


ऐसा लगता है कि वे ng1 से वाक्यविन्यास का समर्थन नहीं करना चाहते हैं।

मिस्को हेवरी के अनुसार (संदर्भ):

मानचित्र में चाबियों में कोई ऑर्डर नहीं है और इसलिए वे पुनरावृत्ति अप्रत्याशित हैं।   यह ng1 में समर्थित था, लेकिन हमें लगता है कि यह एक गलती थी और नहीं   एनजी 2 में समर्थित होना चाहिए

योजना एक नक्शा ToIterable पाइप है

<div *ngFor"var item of map | mapToIterable">

तो अपने ऑब्जेक्ट को फिर से चालू करने के लिए आपको "पाइप" का उपयोग करने की आवश्यकता होगी। वर्तमान में कोई नहीं है पाइप कार्यान्वित किया कि वह करता है।

एक कामकाज के रूप में, यहां एक छोटा सा उदाहरण है जो चाबियों पर फिर से चलाता है:

घटक:

import {Component} from 'angular2/core';

@Component({
  selector: 'component',
  templateUrl: `
       <ul>
       <li *ngFor="#key of keys();">{{key}}:{{myDict[key]}}</li>
       </ul>
  `
})
export class Home {
  myDict : Dictionary;
  constructor() {
    this.myDict = {'key1':'value1','key2':'value2'};
  }

  keys() : Array<string> {
    return Object.keys(this.myDict);
  }
}

interface Dictionary {
    [ index: string ]: string
}

68
2017-07-21 11:22



मैं ऑब्जेक्ट पर कोशिश कर रहा हूं key जैसा number तथा value जैसा string लेकिन कोणीय त्रुटि फेंक रहा है expression has changed after it was checked ? इतना विचार क्यों? - Pardeep Jain
हाँ यह मेरे लिए भी हो रहा है। और अगर मैं @ obsur के समाधान का भी उपयोग करता हूं। - user2294382


इस पाइप का उपयोग करने की कोशिश करो

@Pipe({ name: 'values',  pure: false })
export class ValuesPipe implements PipeTransform {
  transform(value: any, args: any[] = null): any {
    return Object.keys(value).map(key => value[key]);
  }
}

<div *ngFor="#value of object | values"> </div>

60
2017-12-03 19:26



शानदार, और यदि मैं कुंजी को संदर्भ रखना चाहता हूं तो मैं केवल एक वस्तु को दोनों कुंजी और मूल्य के साथ मैप कर दूंगा। काश मैं कई उत्तरों को स्वीकार्य उत्तर के रूप में चिह्नित कर सकता हूं, क्योंकि यह मेरी समस्या का समाधान है, जबकि चिह्नित उत्तर मेरे प्रश्न का उत्तर है। - Rickard Staaf
@obscur - अगर मैं उपरोक्त करता हूं, तो मुझे angular2.beta.0.0 का उपयोग करके "त्रुटि जांचने के बाद अभिव्यक्ति बदल गई है" त्रुटि मिलती है। कोई विचार? - user2294382
Thats क्योंकि शुद्ध: झूठी इंजेक्शन करने के लिए एक परिवर्तन पहचान की आवश्यकता है - Judson Terrell
इसे अशुद्ध करने के लिए क्यों सेट करें? - tom10271


2018 अद्यतन:

जैसा कि अन्य उत्तरों ने उल्लेख किया है, यह एनजीएक्स में समर्थित नहीं है, इसलिए यहां एक कामकाज है कुंजी-मान-जोड़े:

वह पाइप:

import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
  name: 'mapToIterable'
})
export class MapToIterable implements PipeTransform {
  transform(dict: Object) {
    var a = [];
    for (var key in dict) {
      if (dict.hasOwnProperty(key)) {
        a.push({key: key, val: dict[key]});
      }
    }
    return a;
  }
}

उपयोगितायें:

<div *ngFor="let keyValuePair of someObject | mapToIterable">
  This is the key {{keyValuePair.key}} and this is the value {{keyValuePair.val}}.
</div>

Stackblitz उदाहरण: https://stackblitz.com/edit/map-to-iterable-pipe


33
2018-02-08 01:14



आपको जोड़ना चाहिए implements PipeTransform कक्षा परिभाषा में (देखें angular.io/guide/pipes#custom-pipes) - toioski
@toioski धन्यवाद, मैंने इसे जोड़ा है और लूप के नए वाक्यविन्यास में अपडेट किया है। - bersling
महान जवाब, यह मेरे शब्दकोश के लिए ngFor करने के लिए इस्तेमाल किया। मुझे keyValuePair.val करना था [0] हालांकि मेरे मान समाप्त हो गए [{}] और नहीं {} - jhhoff02
धन्यवाद। बहुत अच्छा काम करता है - Johansrk


@ Obscur के उत्तर के अलावा, यहां एक उदाहरण दिया गया है कि आप दोनों को कैसे एक्सेस कर सकते हैं key तथा value @ व्यू से

पाइप:

@Pipe({
   name: 'keyValueFilter'
})

export class keyValueFilterPipe {
    transform(value: any, args: any[] = null): any {

        return Object.keys(value).map(function(key) {
            let pair = {};
            let k = 'key';
            let v = 'value'


            pair[k] = key;
            pair[v] = value[key];

            return pair;
        });
    }

}

राय:

<li *ngFor="#u of myObject | 
keyValueFilter">First Name: {{u.key}} <br> Last Name: {{u.value}}</li>

तो अगर वस्तु इस तरह दिखती थी:

myObject = {
    Daario: Naharis,
    Victarion: Greyjoy,
    Quentyn: Ball
}

उत्पन्न परिणाम होगा:

पहला नाम: दाario
अंतिम नाम: नाहरिस

पहला नाम: विक्टोरियन
अंतिम नाम: ग्रेजॉय

पहला नाम: क्वांटिन
अंतिम नाम: गेंद


18
2018-03-03 18:14



मेरे लिए काफी आसानी से काम किया! धन्यवाद - Vlad
उल्लेख करने के लिए केवल एक चीज आपको दृश्य को बदलने की जरूरत है: as <li *ngFor="let u of myObject | keyValueFilter">First Name: {{u.key}} <br> Last Name: {{u.value}}</li>। मुझसे +1 - sib10
बहुत बढ़िया ! धन्यवाद। - Maxime Lafarie


SimonHawesome के लिए जोड़ना उत्कृष्ट उत्तर। मैंने एक संक्षिप्त संस्करण बनाया है जो कुछ नई टाइपस्क्रिप्ट सुविधाओं का उपयोग करता है। मुझे एहसास है कि अंतर्निहित विवरणों को समझाने के लिए साइमनहॉवेस्ट का संस्करण जानबूझकर वर्बोज़ है। मैंने शुरुआती चेक भी जोड़ा है ताकि पाइप काम करे falsy मान। उदा।, अगर नक्शा है null

ध्यान दें कि एक इटरेटर ट्रांसफॉर्म का उपयोग करना (जैसा कि यहां किया गया है) अधिक कुशल हो सकता है क्योंकि हमें अस्थायी सरणी के लिए स्मृति आवंटित करने की आवश्यकता नहीं है (जैसा कि कुछ अन्य उत्तरों में किया गया है)।

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

@Pipe({
    name: 'mapToIterable'
})
export class MapToIterable implements PipeTransform {
    transform(map: { [key: string]: any }, ...parameters: any[]) {
        if (!map)
            return undefined;
        return Object.keys(map)
            .map((key) => ({ 'key': key, 'value': map[key] }));
    }
}

12
2018-05-27 09:15



इस थ्रेड को प्यार करें, एक टिप्पणी के साथ एक और इमारत पर! जब मैंने आपका कोड देखा तो मैं वही चीज़ लिखने वाला था - David
इस समाधान में एकमात्र चीज: इसे लागू करना चाहिए PipeTransform - iRaS
@iRaS अच्छा बिंदु। मैंने अपना जवाब अपडेट कर लिया है। मैं नल की जगह अपरिभाषित भी लौटता हूं। - Frederik Aalund


यहां कुछ उपरोक्त उत्तरों पर एक भिन्नता है जो एकाधिक परिवर्तनों (कुंजीवाल, कुंजी, मान) का समर्थन करता है:

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

type Args = 'keyval'|'key'|'value';

@Pipe({
  name: 'mapToIterable',
  pure: false
})
export class MapToIterablePipe implements PipeTransform {
  transform(obj: {}, arg: Args = 'keyval') {
    return arg === 'keyval' ?
        Object.keys(obj).map(key => ({key: key, value: obj[key]})) :
      arg === 'key' ?
        Object.keys(obj) :
      arg === 'value' ?
        Object.keys(obj).map(key => obj[key]) :
      null;
  }
}

प्रयोग

map = {
    'a': 'aee',
    'b': 'bee',
    'c': 'see'
}

<div *ngFor="let o of map | mapToIterable">{{o.key}}: {{o.value}}</div>
  <div>a: aee</div>
  <div>b: bee</div>
  <div>c: see</div>

<div *ngFor="let o of map | mapToIterable:'keyval'">{{o.key}}: {{o.value}}</div>
  <div>a: aee</div>
  <div>b: bee</div>
  <div>c: see</div>

<div *ngFor="let k of map | mapToIterable:'key'">{{k}}</div>
  <div>a</div>
  <div>b</div>
  <div>c</div>

<div *ngFor="let v of map | mapToIterable:'value'">{{v}}</div>
  <div>aee</div>
  <div>bee</div>
  <div>see</div>

9
2018-01-11 22:32



pure: false तत्काल प्रतिबिंब के लिए वास्तव में महत्वपूर्ण है। - Fırat KÜÇÜK


मेरे पास एक समान समस्या थी, वस्तुओं और मानचित्रों के लिए कुछ बनाया।

import { Pipe } from 'angular2/core.js';

/**
 * Map to Iteratble Pipe
 * 
 * It accepts Objects and [Maps](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map)
 * 
 * Example:
 * 
 *  <div *ngFor="#keyValuePair of someObject | mapToIterable">
 *    key {{keyValuePair.key}} and value {{keyValuePair.value}}
 *  </div>
 * 
 */
@Pipe({ name: 'mapToIterable' })
export class MapToIterable {
  transform(value) {
    let result = [];
    
    if(value.entries) {
      for (var [key, value] of value.entries()) {
        result.push({ key, value });
      }
    } else {
      for(let key in value) {
        result.push({ key, value: value[key] });
      }
    }

    return result;
  }
}


4
2018-04-13 23:27



यह अच्छा काम करता है, सिवाय इसके कि टाइपस्क्रिप्ट में आपको जोड़ना चाहिए implements PipeTransform कक्षा परिभाषा के लिए - GeorgDangl


कोणीय 2.x && कोणीय 4.x बॉक्स के बाहर इसका समर्थन नहीं करते हैं

आप इन दोनों पाइपों को या तो फिर से शुरू करने के लिए उपयोग कर सकते हैं कुंजी या द्वारा मूल्य

कुंजी पाइप:

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

@Pipe({
  name: 'keys',
  pure: false
})
export class KeysPipe implements PipeTransform {
  transform(value: any, args: any[] = null): any {
    return Object.keys(value)
  }
}

मूल्य पाइप:

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

@Pipe({
  name: 'values',
  pure: false
})
export class ValuesPipe implements PipeTransform {
  transform(value: any, args: any[] = null): any {
    return Object.keys(value).map(key => value[key])
  }
}

कैसे इस्तेमाल करे:

let data = {key1: 'value1', key2: 'value2'}

<div *ngFor="let key of data | keys"></div>
<div *ngFor="let value of data | values"></div>

3
2018-05-30 06:15