Я пытаюсь сделать что-то в Angular 2 Alpha 28, и у меня проблема со словарями и NgFor.
У меня есть интерфейс на TypeScript, который выглядит так:
interface Dictionary {
[ index: string ]: string
}
В JavaScript это будет преобразовано в объект, который с данными может выглядеть так:
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'»
Что мне здесь не хватает? Это больше невозможно? (Первый синтаксис работает в Angular 1.x) или отличается ли синтаксис для итерации по объекту?
Ответы:
Похоже, они не хотят поддерживать синтаксис из ng1.
По словам Мишко Хевери ( ссылка ):
Итак, чтобы перебрать ваш объект, вам нужно будет использовать «канал». В настоящее время не существует канала, который бы это делал.
В качестве обходного пути вот небольшой пример, который перебирает ключи:
Составная часть:
источник
key
asnumber
иvalue
as,string
но angular выдает ошибкуexpression has changed after it was checked
? почему так возникла идея?Angular 6.1.0+ Ответ
Используйте встроенный
keyvalue
-pipe следующим образом:или вот так:
где
mySortingFunction
находится в вашем.ts
файле, например:Stackblitz: https://stackblitz.com/edit/angular-iterate-key-value
Вам не нужно регистрировать это в каком-либо модуле, поскольку каналы Angular работают из коробки в любом шаблоне.
Это также работает для Javascript-Maps .
источник
implements PipeTransform
определение класса (см. Angular.io/guide/pipes#custom-pipes )return Object.keys(dict).map(key => ({key, val: dict[key]}))
?попробуй использовать эту трубу
источник
В дополнение к ответу @ obscur вот пример того, как вы можете получить доступ как к @View, так
key
иvalue
из него.Труба:
Посмотреть:
Итак, если бы объект выглядел так:
Сгенерированный результат будет:
Имя: Даарио
Фамилия: Нахарис
Имя: Виктарион
Фамилия: Грейджой
Имя: Квентин
Фамилия: Болл
источник
<li *ngFor="let u of myObject | keyValueFilter">First Name: {{u.key}} <br> Last Name: {{u.value}}</li>
. +1 от меня.return { 'key' : key, 'value' : value[key] };
Обновлено: Angular теперь предоставляет канал для отсечения объекта json через
keyvalue
:РАБОЧАЯ ДЕМО , подробнее читайте в
Ранее (для более старой версии): до сих пор лучший / самый короткий ответ, который я нашел, - (без фильтра трубы или пользовательской функции со стороны компонента)
РАБОЧАЯ ДЕМО
источник
let item of myDict | keyvalue
это решило мою проблему.Добавление к отличному ответу SimonHawesome . Я сделал сжатую версию, в которой используются некоторые новые функции машинописного текста. Я понимаю, что версия SimonHawesome намеренно многословна, чтобы объяснить основные детали. Я также добавил раннюю проверку, чтобы канал работал с ложными значениями. Например, если карта есть
null
.Обратите внимание, что использование преобразования итератора (как сделано здесь) может быть более эффективным, поскольку нам не нужно выделять память для временного массива (как это сделано в некоторых других ответах).
источник
PipeTransform
Вот вариант некоторых из приведенных выше ответов, который поддерживает несколько преобразований (keyval, key, value):
использование
источник
pure: false
действительно важно для мгновенных отражений.У меня была аналогичная проблема, построил что-то для объектов и карт.
источник
implements PipeTransform
определение классаAngular 2.x && Angular 4.x не поддерживает это из коробки
Вы можете использовать эти два канала для итерации по ключу или по значению .
Ключи трубы:
Труба значений:
Как пользоваться:
источник
Если кому-то интересно, как работать с многомерным объектом, вот решение.
Допустим, у нас есть следующий объект в обслуживании
в компонент добавить следующую функцию
наконец в виду сделать следующее
источник
Я рвал на себе волосы, пытаясь проанализировать и использовать данные, возвращенные из запроса JSON / вызова API. Я не уверен, где именно я ошибся, мне кажется, что я обдумывал ответ несколько дней, гоняясь за различными кодами ошибок, например:
«Не удается найти поддерживающий объект канала 'iterableDiff'»
«Для универсального массива типов требуется один аргумент»
Ошибки синтаксического анализа JSON, и я уверен, что другие
Я предполагаю, что у меня просто неправильная комбинация исправлений.
Итак, вот краткое изложение ошибок и вещей, на которые стоит обратить внимание.
Сначала проверьте результат ваших вызовов API, ваши результаты могут быть в форме объекта, массива или массива объектов.
Я не буду вдаваться в подробности, достаточно сказать, что исходная ошибка OP из-за отсутствия итерации обычно вызвана тем, что вы пытаетесь выполнить итерацию объекта, а не массива.
Вот некоторые из моих результатов отладки, показывающие переменные как массивов, так и объектов
Итак, поскольку мы обычно хотели бы перебрать наш результат JSON, нам нужно убедиться, что он имеет форму массива. Я пробовал множество примеров и, возможно, зная то, что я знаю сейчас, некоторые из них на самом деле будут работать, но подход, который я использовал, действительно заключался в реализации канала, а код, который я использовал, заключался в том, что отправлено t.888
Честно говоря, я думаю, что одной из вещей, которые меня вызывали, было отсутствие обработки ошибок, добавив вызов `` return undefined '', я считаю, что теперь мы разрешаем отправку непредвиденных данных в канал, что, очевидно, происходило в моем случае ,
если вы не хотите иметь дело с аргументом канала (и посмотрите, я не думаю, что это необходимо в большинстве случаев), вы можете просто вернуть следующее
Некоторые примечания по созданию канала и страницы или компонента, использующего этот канал
я получал ошибки о том, что "name_of_my_pipe" не найдено
Используйте команду 'ionic generate pipe' из интерфейса командной строки, чтобы убедиться, что файлы pipe modules.ts созданы и указаны правильно. убедитесь, что вы добавили следующее на страницу mypage.module.ts.
(не уверен, что это изменится, если у вас также есть собственный custom_module, вам также может потребоваться добавить его в custommodule.module.ts)
если вы использовали команду 'ionic generate page' для создания своей страницы, но решили использовать эту страницу в качестве главной, не забудьте удалить ссылку на страницу из app.module.ts (вот еще один ответ, который я опубликовал, касающийся этого https: / /forum.ionicframework.com/t/solved-pipe-not-found-in-custom-component/95179/13?u=dreaser
В моем поиске ответов там, где есть несколько способов отображения данных в файле html, и я недостаточно понимаю, чтобы объяснить различия. Возможно, вам будет лучше использовать одно вместо другого в определенных сценариях.
Однако то, что сработало, позволило мне отобразить и значение, и ключ, было следующим:
чтобы вызвать API, похоже, вам нужно импортировать HttpModule в app.module.ts
и вам нужен Http на странице, с которой вы звоните
При вызове API кажется, что вы можете получить доступ к дочерним данным (объектам или массивам в массиве) двумя разными способами, либо они работают.
либо во время звонка
или когда вы назначаете данные своей локальной переменной
(не уверен, что эта переменная должна быть строкой массива, но это то, что у меня есть сейчас. Она может работать как более общая переменная)
И последнее замечание: не было необходимости использовать встроенную библиотеку JSON, однако вы можете найти эти 2 вызова удобными для преобразования из объекта в строку и наоборот.
Я надеюсь, что эта подборка информации кому-то поможет.
источник
источник
Интерфейсы в TypeScript - это конструкция времени разработки (исключительно для инструментов ... 0 влияние времени выполнения). Вы должны написать тот же TypeScript, что и ваш JavaScript.
источник
Словарь - это объект, а не массив. Я считаю, что ng-repeat требует массива в Angular 2.
Самым простым решением было бы создать канал / фильтр, который на лету преобразует объект в массив. Тем не менее, вы, вероятно, захотите использовать массив, как говорит @basarat.
источник
Если у вас есть
es6-shim
или вашаtsconfig.json
цельes6
, вы можете использовать ES6 Map, чтобы сделать это.источник
Определите
MapValuesPipe
и реализуйте PipeTransform :Добавьте трубку в модуль труб. Это важно, если вам нужно использовать одну и ту же трубу в нескольких компонентах :
Затем просто используйте канал в своем html с помощью
*ngFor
:<tr *ngFor="let attribute of mMap | mapValuesPipe">
Помните, вам нужно будет объявить свой PipesModule в компоненте, в котором вы хотите использовать канал:
источник
Поэтому я собирался реализовать свою собственную вспомогательную функцию objLength (obj), которая возвращает только Object (obj) .keys.length. Но затем, когда я добавлял его в свою функцию template * ngIf, моя IDE предложила objectKeys (). Я попробовал, и это сработало. Следуя его объявлению, кажется, что он предлагается lib.es5.d.ts, так что готово!
Вот как я это реализовал (у меня есть собственный объект, который использует ключи, сгенерированные на стороне сервера, в качестве индекса для загруженных мной файлов):
источник