Как правильно выполнить функцию внутри 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.