状況:
AngularJsで権限を割り当てるアプリを作成しています。これを行うには、3つのネストされたng-repeatがあります。
最初のループ:権限グループを表示
2番目のループ:各権限グループについて、カテゴリを表示します。このループ内で、各カテゴリのすべてのサブカテゴリを取得する関数を実行します
3番目のループ:サブカテゴリーを表示
問題:
問題は、2番目のループ内の関数の実行にあります。
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;
});
}
Teの動作は非常に奇妙です。おそらくダーティチェックのため、ページは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;
});
}
今回はページが一度だけロードされます。ボタンを押すと、適切なサブカテゴリが表示されますが、もちろん対応するカテゴリだけでなくFOR ALLも表示されます。これは、グローバルスコープの変数を変更しているためです。
目的:
取得したいのは、各カテゴリの適切なサブカテゴリをすべて表示することです。ボタンを使用せずに、ページが読み込まれるとすぐに適切なコンテンツがすべて表示されます。しかし、AngularJsでこれをどのように適切に行うことができるかわかりません。
質問:
ループごとに異なるデータを返し、表示する関数をng-repeat内で適切に実行するにはどうすればよいですか?
[〜#〜] edit [〜#〜]-1つのカテゴリのサブカテゴリの例のダンプ:
[{
"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;
}}])
サブカテゴリの例は私のケースでは機能せず、何らかの理由でコードが無限ループに陥りました。アコーディオンを使っていたからかもしれません。
私はng-initを使用してng-repeat内でこの関数呼び出しを達成しました
<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' }
});
});
カテゴリのファクトリを作成し、get_sub_categories関数をこの新しいファクトリに移動します。
ここでの良い解決策は、Angular Directive。
ここでng-repeatで使用されるディレクティブの例を見ることができます: Angular Directiveは評価されませんng-repeat
ディレクティブの詳細については、公式ドキュメントを確認できます。 https://docs.angularjs.org/guide/directive