Как использовать ng-repeat для словарей в AngularJs?


285

Я знаю, что мы можем легко использовать ng-repeat для json-объектов или массивов, таких как:

<div ng-repeat="user in users"></div>

но как мы можем использовать ng-repeat для словарей, например:

var users = null;
users["182982"] = "{...json-object...}";
users["198784"] = "{...json-object...}";
users["119827"] = "{...json-object...}";

Я хочу использовать это со словарем пользователей:

<div ng-repeat="user in users"></div>

Является ли это возможным?. Если да, как я могу сделать это в AngularJs?

Пример для моего вопроса: в C # мы определяем словари как:

Dictionary<key,value> dict = new Dictionary<key,value>();

//and then we can search for values, without knowing the keys
foreach(var val in dict.Values)
{
}

Есть ли встроенная функция, которая возвращает значения из словаря, как в C #?


1
В чем разница между словарем и объектом JSON? Я считаю, что нет ни одного в javascript!
Markmarijnissen

8
@markmarijnissen: объект JSON имеет более строгие правила синтаксиса, чем объект JavaScript . И, как мы уже находимся в углу Педанта, в JavaScript не существует такого понятия, как «словарь». Мы просто называем их объектами.
Пол Д. Уэйт

Ответы:


556

Ты можешь использовать

<li ng-repeat="(name, age) in items">{{name}}: {{age}}</li>

Смотрите документацию ngRepeat . Пример: http://jsfiddle.net/WRtqV/1/


53
Это не то, что я спросил, а именно то, что я хотел. Спасибо Артем Андреев
Вурал

1
Как мы можем использовать фильтр в этом нг-повтор. Это не работает в моем случае, когда я использую поисковый фильтр. Произнесите <input type = "text" ng-model = "searchText" /> <li ng-repeat = "(имя, возраст) в элементах | filter: searchText"> {{name}}: {{age}} </ li> ...
Шехар

1
@Shekhar Filter «фильтр» работает только с массивами. Вы можете попробовать создать запрос функции.
Артем Андреев

2
Приятно видеть некоторую общность с питоном :)
Роберт

4
Вы можете получить функцию фильтрации даже для словарей (объектов), используя оператор ng-if .. как, например: <li ng-repeat = "(id, obj) в элементах" ng-if = 'obj.sex = "female "'> {{obj.name}} {{obj.surname}} </ li> ... где items - это набор людей, проиндексированных по некоторому ключу.
giowild

27

Я также хотел бы упомянуть новую функциональность AngularJSng-repeat , а именно, специальные повторные начальную и конечную точки . Эта функциональность была добавлена ​​для того, чтобы повторять серию HTML-элементов вместо одного родительского HTML-элемента.

Для того , чтобы начать и конечное использование повторителя точек необходимо определить их с помощью ng-repeat-startи ng-repeat-endдиректив соответственно.

ng-repeat-startДиректива работает очень похожа на ng-repeatдирективу. Разница в том, что он будет повторять все элементы HTML (включая тег, для которого он определен) до конечного тега HTML, в ng-repeat-endкоторый помещается (включая тег с ng-repeat-end).

Пример кода (от контроллера):

// ...
$scope.users = {};
$scope.users["182982"] = {name:"John", age: 30};
$scope.users["198784"] = {name:"Antonio", age: 32};
$scope.users["119827"] = {name:"Stephan", age: 18};
// ...

Образец HTML-шаблона:

<div ng-repeat-start="(id, user) in users">
    ==== User details ====
</div>
<div>
    <span>{{$index+1}}. </span>
    <strong>{{id}} </strong>
    <span class="name">{{user.name}} </span>
    <span class="age">({{user.age}})</span>
</div>

<div ng-if="!$first">
   <img src="/some_image.jpg" alt="some img" title="some img" />
</div>
<div ng-repeat-end>
    ======================
</div>

Вывод будет выглядеть примерно так (в зависимости от стиля HTML):

==== User details ====
1.  119827 Stephan (18)
======================
==== User details ====
2.  182982 John (30)
[sample image goes here]
======================
==== User details ====
3.  198784 Antonio (32)
[sample image goes here]
======================

Как видите, ng-repeat-startповторяются все элементы HTML (включая элемент с ng-repeat-start). Все ng-repeatспециальные свойства (в данном случае $firstи $index) также работают как положено.


Ошибка: [$ compile: uterdir] Не определен атрибут, найдено «ng-repeat-start», но не найдено ни одного подходящего «ng-repeat-end».
zloctb

@zloctb Вы, должно быть, пропустили <div ng-repeat-end>..</div>в своей разметке
Джон Кастер

6

Разработчики JavaScript склонны ссылаться на вышеупомянутую структуру данных как объект или хэш вместо словаря.

Ваш синтаксис выше неправильный, так как вы инициализируете usersобъект как нулевой. Я предполагаю, что это опечатка, так как код должен читать:

// Initialize users as a new hash.
var users = {};
users["182982"] = "...";

Чтобы извлечь все значения из хеша, вам нужно перебрать его, используя цикл for:

function getValues (hash) {
    var values = [];
    for (var key in hash) {

        // Ensure that the `key` is actually a member of the hash and not
        // a member of the `prototype`.
        // see: http://javascript.crockford.com/code.html#for%20statement
        if (hash.hasOwnProperty(key)) {
            values.push(key);
        }
    }
    return values;
};

Если вы планируете много работать со структурами данных в JavaScript, то библиотека underscore.js определенно стоит посмотреть. Подчеркивание поставляется с valuesметодом, который выполнит вышеуказанную задачу для вас:

var values = _.values(users);

Я сам не использую Angular, но я почти уверен, что будет встроен удобный метод для перебора значений хеша (ага, вот так, Артем Андреев дает ответ выше :))


1
+1 для underscore.js и этой полезной информации. Спасибо Джонни!
Vural

0

В Angular 7 будет работать следующий простой пример (при условии, что словарь находится в переменной с именем d):

my.component.ts:

keys: string[] = [];  // declaration of class member 'keys'
// component code ...

this.keys = Object.keys(d);

my.component.html: (отобразит список пар ключ: значение)

<ul *ngFor="let key of keys">
    {{key}}: {{d[key]}}
</ul>
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.