我有一个应用程序使用多个选项卡,每个选项卡中都有一个网格。我有多个页面使用相同的配置。
我有一个适用于所有网格的控制器。我想在整个应用程序中重用这个控制器。
我的问题是我试图延迟加载每个选项卡的数据,直到单击该选项卡。我想不通的是如何告诉控制器哪个范围属于哪个选项卡,并且只获取该网格的数据。我在内部知道 AngularJs 会这样做,因为如果我一次加载每个选项卡的所有数据,我可以单击每个选项卡的分页器、搜索等,并且只更新该范围。
我为每个选项卡设置了 ng-click 设置,并且可以在单击选项卡时触发我的控制器。但是,控制器调用所有实例化的范围来为它们各自的网格加载数据。
我的方法可能不是最好的,但创建执行完全相同操作的单独控制器似乎很愚蠢。
注意:带有引导程序的 Angular UI 选项卡不是一个选项。
我的观点
<div ng-app="TabsApp">
<div tabs>
<div class="tabs">
<a ng-click="clickTab(0)" ng-class="{selected: selectedTab==0}">Localized Text From Server</a>
<a ng-click="clickTab(1)" ng-class="{selected: selectedTab==1}">Localized Text From Server</a>
<a ng-click="clickTab(2)" ng-class="{selected: selectedTab==2}">Localized Text From Server</a>
</div>
<div class="tab-content">
<div ng-show="selectedTab==0" ng-init="init(@Model.UserId, 'useraddresses')" ng-controller="ListCtrl">@Html.Partial("_Grid0")</div>
<div ng-show="selectedTab==1" ng-init="init(@Model.UserId, 'userphones')" ng-controller="ListCtrl">@Html.Partial("_Grid1")</div>
<div ng-show="selectedTab==2" ng-init="init(@Model.UserId, 'usernotes')" ng-controller="ListCtrl">@Html.Partial("_Grid2")</div>
</div>
</div>
</div>
我的应用和工厂网址
var TabsApp = angular.module("TabsApp", ['ngResource', 'ngRoute']);
TabsApp.factory('Api', function($resource){
return $resource('/api/user/:userId/:ctrl', { userId: '@userId', ctrl: '@ctrl'});
});
我的控制器 - 子范围
var ListCtrl = function ($scope, $location, Api){
$scope.search = function () {
Api.get({
userId: $scope.userId,
ctrl: $scope.ctrl,
q: $scope.query
//etc.
},
function(data){
$scope.items = data.items;
//other mapping
});
};
$scope.init = function(userId, ctrl){
$scope.userId = userId;
$scope.ctrl = ctrl;
};
$scope.reset = function(){
$scope.items = [];
$scope.search();
};
//kind of a hack but broadcasting was the only way I could figure out to listen for tab changes
$scope.tabModelChange = { 'isChanged': false };
$scope.$on('tabModelChange', function(event, args) {
$scope.tabModelChange.isChanged = true;
var activeTab = args.val[$scope.selectedTab];
if (!activeTab.isLoaded) {
$scope.reset();
}
});
//filtering, sorting, pagination, etc.
};
我的指令:父范围
TabsApp.directive('tabs', function () {
return {
controller: function ($scope, $element) {
$scope.selectedTab = 0;
$scope.tabModel = [];
//I use localized text and any number of tabs on my views from the server so the client wont know how many tabs each view will have
var tabs = angular.element($element.children()[1]).children();
angular.forEach(tabs, function (value, key) {
$scope.tabModel.push({'isLoaded' : false, 'isActive': false});
});
$scope.clickTab = function(tab) {
$scope.selectedTab = tab;
$scope.tabModel[$scope.selectedTab].isActive = true;
};
$scope.$watch('tabModel', function(newVal, oldVal) {
if (newVal !== oldVal) {
$scope.$broadcast('tabModelChange', { 'val': newVal });
}
}, true);
}
};
});
我怀疑当我的控制器收到选项卡模型已更改的广播时,它会调用 $scope.reset ,其中 $scope 是父范围,然后遍历子范围寻找“重置”。因为有 3 个 ListCtrl 实例,所以父作用域会找到 3 个带有“reset”的子作用域。因此,所有数据都会立即加载。
如何获得 $scope.reset 以匹配单击的选项卡?谢谢。