СИТУАЦИЯ:
Я делаю приложение в 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, которая возвращает и отображает разные данные для каждого цикла?
EDIT – ДАМП ПРИМЕРЫ СУБАТОРИЙ ДЛЯ ОДНОЙ КАТЕГОРИИ:
[{ "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" }]
Вызов функции внутри 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; }}])
Пример подкатегории не работал для моего случая, и по какой-то причине мой код попал в цикл 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 выглядит следующим образом:
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' } }); });
Я считаю, что хорошим решением здесь является использование Angular Directive.
Вы можете увидеть пример директивы, используемой в ng-repeat здесь: Угловая директива не оценивает внутри ng-repeat
Для получения дополнительной информации о директивах вы можете проверить официальную документацию: https://docs.angularjs.org/guide/directive
Я бы создал фабрику для категории, а затем переместил вашу функцию get_sub_categories на этот новый завод.