Как правильно выполнить функцию внутри ng-repeat
СИТУАЦИЯ:
Я делаю приложение в AngularJs, которое назначает разрешения.
Для этого у меня есть три вложенных ng-repeat.
Первый цикл: отображает группу PERMISSION GROUP
Второй цикл: для каждой группы разрешений отображаются КАТЕГОРИИ.
Внутри этого цикла выполните функцию, которая получит все КАТЕГОРЫ SUB для каждой категории
Третий цикл: отображение SUB CATEGORIES
ВОПРОС:
Проблема заключается в выполнении функции внутри второго цикла.
ATTEMPT 1 - ng-init:
<div class="row" ng-repeat="permission_group in list_permission_groups">
<div class="col-sm-3">
<h3>
{{permission_group.permission_group_name}}
</h3>
</div>
<div class="col-sm-9">
<ul>
<li ng-repeat="category in list_categories">
<span>
{{ category.name }}
</span>
<div class="checkbox">
<label>
<div ng-init="temp_result = get_Sub_Categories(category.category_id)">
<p ng-repeat="sub_category in temp_result">
{{ sub_category.name }}
</p>
</div>
</label>
</div>
</li>
</ul>
</div>
</div>
В контроллере:
$scope.get_Sub_Categories = function(category_id) {
$http({
url: base_url + 'main/json_get_list_sub_categories',
data: {
category_id: category_id
},
method: "POST"
}).success(function(data) {
return data;
});
}
Те поведение довольно странно. Потенциально из-за грязной проверки страница загружается 682 раза.
Результат не отображается.
ATTEMPT 2 - ng-click: (только для отладки)
<div class="row" ng-repeat="permission_group in list_permission_groups">
<div class="col-sm-3">
<h3>
{{permission_group.permission_group_name}}
</h3>
</div>
<div class="col-sm-9">
<ul>
<li ng-repeat="category in list_categories">
<span>
{{ category.name }}
</span>
<div class="checkbox">
<label>
<button ng-click="get_Sub_Categories(category.category_id)">
GET SUB-CATEGORIES
</button>
{{ list_sub_categories }}
</label>
</div>
</li>
</ul>
</div>
</div>
В контроллере:
$scope.get_Sub_Categories = function(category_id) {
$http({
url: base_url + 'main/json_get_list_sub_categories',
data: {
category_id: category_id
},
method: "POST"
}).success(function(data) {
$scope.list_sub_categories = data;
});
}
На этот раз страница загружается только один раз.
Если я нажимаю кнопку, отображаются соответствующие подкатегории, но, конечно, не только для соответствующей категории, но и для ВСЕГО, потому что я изменяю var в глобальной области.
ЦЕЛЬ:
То, что я хочу получить, просто отображает все соответствующие подкатегории для каждой категории.
Без использования кнопки, но просто посмотрите все правильное содержимое, как только загрузится страница.
Но я не понимаю, как это можно сделать правильно в AngularJs.
ВОПРОС:
Как я могу правильно выполнить функцию внутри ng-repeat, которая возвращает и отображает разные данные для каждого цикла?
РЕДАКТИРОВАТЬ - ДАМП ПРИМЕРЫ СУБ-КАТЕГОРИЙ ДЛЯ ОДНОЙ КАТЕГОРИИ:
[{
"sub_category_id": "1",
"name": "SUB_CATEGORY_1",
"category_id_parent": "1",
"status": "VISIBLE"
}, {
"sub_category_id": "2",
"name": "SUB_CATEGORY_2",
"category_id_parent": "1",
"status": "VISIBLE"
}, {
"sub_category_id": "3",
"name": "SUB_CATEGORY_3",
"category_id_parent": "1",
"status": "VISIBLE"
}, {
"sub_category_id": "4",
"name": "SUB_CATEGORY_4",
"category_id_parent": "1",
"status": "VISIBLE"
}]
Ответы
Ответ 1
Вызов функции внутри ng-repeat аналогичен нормальной. Поскольку вам нужно отображать подкатегории во время загрузки страницы, лучше получить эти данные заранее.
Асинхронная загрузка подкатегорий не будет вписываться в этот сценарий.
Ниже приведен минимальный фрагмент (JS Fiddle)
<div ng-app="app" ng-controller="ctrl">
<div ng-repeat="category in model.categories"> <span> Category: {{ category.name }} </span>
<p ng-repeat="subCategory in getSubCategories(category.Id)">{{ subCategory.name }}</p>
</div>
</div>
контроллер
angular.module("app", [])
.controller('ctrl', ['$scope', function ($scope) {
$scope.model = {
categories: [{
"Id": 1,
name: '1'
}, {
"Id": 2,
name: '2'
}],
subCategories: [{
"parentId": 1,
name: 'a1'
}, {
"parentId": 1,
name: 'a2'
},
{
"parentId": 2,
name: 'a3'
}]
}
$scope.getSubCategories = function(parentId){
var result = [];
for(var i = 0 ; i < $scope.model.subCategories.length ; i++){
if(parentId === $scope.model.subCategories[i].parentId){
result.push($scope.model.subCategories[i]);
}
}
console.log(parentId)
return result;
}}])
Ответ 2
Пример подкатегории не работал для моего случая, и по какой-то причине мой код попал в цикл infinte. может быть потому, что я использовал аккордеон.
Я выполнил этот вызов функции внутри ng-repeat, используя ng-init
<td class="lectureClass" ng-repeat="s in sessions" ng-init='presenters=getPresenters(s.id)'>
{{s.name}}
<div class="presenterClass" ng-repeat="p in presenters">
{{p.name}}
</div>
</td>
Код на стороне контроллера должен выглядеть ниже
$scope.getPresenters = function(id) {
return SessionPresenters.get({id: id});
};
Хотя API factory выглядит следующим образом:
angular.module('tryme3App').factory('SessionPresenters', function ($resource, DateUtils) {
return $resource('api/session.Presenters/:id', {}, {
'query': { method: 'GET', isArray: true},
'get': {
method: 'GET', isArray: true
},
'update': { method:'PUT' }
});
});
Ответ 3
Я думаю, что хорошим решением здесь будет использование директивы Angular.
Здесь вы можете увидеть пример директивы, используемой в ng-repeat: Angular Директива не оценивает внутри ng-repeat
Для получения дополнительной информации о директивах вы можете проверить официальную документацию: https://docs.angularjs.org/guide/directive
Ответ 4
Я бы создал factory для категории, а затем переместил вашу функцию get_sub_categories в этот новый factory.