当配置选项来自service时,Angular中的控件会中断
Controls in Angular break when configuration options come from service
我有一个服务,将返回我的一些配置选项的ng-grid
。getGridOptions函数以使用它的控制器的名称为参数,并返回正确的选项集(为了简单起见,这里只显示了一个)。
ng-grid选项服务:
angular.module('services').service('GridOptionsService',function(){
var documents = {
data: 'myData',
enablePaging: true,
showFooter:true,
totalServerItems: 'totalServerItems',
pagingOptions: {
pageSizes: [50,100,200],
pageSize: 50,
currentPage: 1
},
filterOptions: {
filterText: '',
useExternalFilter: false
},
enableCellEdit: false,
enableColumnReordering: true,
enablePinning: false,
showGroupPanel: false,
groupsCollapsedByDefault: true,
enableColumnResize: true,
showSelectionCheckbox: true,
selectWithCheckboxOnly: true,
columnDefs: [
{field:'docId', displayName:'Document ID', cellTemplate: NgGridDomUtil.toLink('#/documents/{{row.getProperty(col.field)}}')},
{field:'docTags', displayName:'Tags'},
{field:'lastSaveDate', displayName:'Last saved'},
{field:'documentVersion', displayName:'Version', width: 120},
{field:'busDocId', displayName:'Customer Doc ID'},
{field:'markedForDelete', displayName:'Deleted', width: 120, cellTemplate: NgGridDomUtil.toCheckbox('{{row.getProperty(col.field)}}')}]
};
var gridOptionManager = {
documents: documents
}
return {
getGridOptions: function(controllerName){
return gridOptionManager[controllerName];
}
}
})
NgGridDomUtil类只是让它更容易在网格上设置样式:
var NgGridDomUtil = (function(){
var toLink = function(href){
var html = '<div class="ngCellText" ng-class="col.colIndex()"><a ng-href= "'+href+'" class="ngCellLink"><span ng-cell-text>{{row.getProperty(col.field)}}</span></a></div>'
return html;
}
var toCheckbox = function(_selected){
var html = '<div class="ngCellText" ng-class="col.colIndex()"><input type="checkbox" ng-change="console.log('+"TEST"+')" ng-model="COL_FIELD" ng-input="COL_FIELD"' + (_selected ? 'selected' : '') + ' /></div>'
return html
}
return {
toLink: toLink,
toCheckbox: toCheckbox
}
})();
我的问题是,当我使用GridOptionsService检索数据时,数据仍然正确地呈现给网格,但文本过滤不再工作,分页被破坏。然而,selectedFilterOption
仍然工作。
控制器:
angular.module('controllers').controller('Repository', ['$scope', 'DataContext','GridOptionsService','$http', function($scope, DataContext,GridOptionsService,$http) {
$scope.filterOptions = {
filterText: '',
useExternalFilter: false
};
$scope.totalServerItems =0;
$scope.pagingOptions ={
pageSizes: [5,10,100],
pageSize: 5,
currentPage: 1
}
//filter!
$scope.dropdownOptions = [{
name: 'Show all'
},{
name: 'Show active'
},{
name: 'Show trash'
}];
//default choice for filtering is 'show active'
$scope.selectedFilterOption = $scope.dropdownOptions[1];
//three stage bool filter
$scope.customFilter = function(data){
var tempData = [];
angular.forEach(data,function(item){
if($scope.selectedFilterOption.name === 'Show all'){
tempData.push(item);
}
else if($scope.selectedFilterOption.name ==='Show active' && !item.markedForDelete){
tempData.push(item);
}
else if($scope.selectedFilterOption.name ==='Show trash' && item.markedForDelete){
tempData.push(item);
}
});
return tempData;
}
//grabbing data
$scope.getPagedDataAsync = function(pageSize, page, searchText){
var data;
if(searchText){
var ft = searchText.toLowerCase();
DataContext.getDocuments().success(function(largeLoad){
//filter the data when searching
data = $scope.customFilter(largeLoad).filter(function(item){
return JSON.stringify(item).toLowerCase().indexOf(ft) != -1;
})
$scope.setPagingData($scope.customFilter(data),page,pageSize);
})
}
else{
DataContext.getDocuments().success(function(largeLoad){
var testLargeLoad = $scope.customFilter(largeLoad);
//filter the data on initial page load when no search text has been entered
$scope.setPagingData(testLargeLoad,page,pageSize);
})
}
};
//paging
$scope.setPagingData = function(data, page, pageSize){
var pagedData = data.slice((page -1) * pageSize, page * pageSize);
//filter the data for paging
$scope.myData = $scope.customFilter(pagedData);
$scope.myData = pagedData;
$scope.totalServerItems = data.length;
// if(!$scope.$$phase){
// $scope.$apply();
// }
}
//watch for filter option change, set the data property of gridOptions to the newly filtered data
$scope.$watch('selectedFilterOption',function(){
var data = $scope.customFilter($scope.myData);
$scope.myData = data;
$scope.getPagedDataAsync($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage);
$scope.setPagingData($scope.myData,$scope.pagingOptions.currentPage,$scope.pagingOptions.pageSize);
})
$scope.$watch('pagingOptions',function(newVal, oldVal){
$scope.getPagedDataAsync($scope.pagingOptions.pageSize,$scope.pagingOptions.currentPage,$scope.filterOptions.filterText);
$scope.setPagingData($scope.myData,$scope.pagingOptions.currentPage,$scope.pagingOptions.pageSize);
},true)
$scope.message ="This is a message";
$scope.gridOptions = {
data: 'myData',
enablePaging: true,
showFooter:true,
totalServerItems: 'totalServerItems',
pagingOptions: $scope.pagingOptions,
filterOptions: $scope.filterOptions,
enableCellEdit: true,
enableColumnReordering: true,
enablePinning: true,
showGroupPanel: true,
groupsCollapsedByDefault: true,
enableColumnResize: true
}
$scope.gridOptions = GridOptionsService.getGridOptions('documents');
//get the data on page load
$scope.getPagedDataAsync($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage);
}]);
我硬编码到控制器中的网格选项与服务返回的网格选项相同。我不明白的是为什么网格呈现,下拉过滤器工作,但分页被打破,只有当网格的选项来自一个服务?但如果它硬编码到控制器中,它就会像预期的那样工作。
编辑:如果有人能更雄辩地陈述我的问题,请随意编辑标题。
我真的不知道ngrid是如何实现的,但是我知道在许多指令中存在一个常见的陷阱,就是它们期望它们的配置在初始化后就准备好。这意味着,它们不会观察配置对象,而是假设它存在,并直接在link'controller函数中使用它,该函数在创建后立即运行。
如果确实是这种情况,一个快速的解决方法是只有当你有配置对象时才初始化指令。假设你通过作用域中的变量'options'传递配置对象,然后你会这样写:
<!-- If options exists on your scope, it means you fetched it from the server -->
<div ng-if="options">
<div ng-grid ng-grid-options="options"></div>
</div>
再次,我不熟悉ngrid或它的用法,这只是一个有根据的猜测,采取结论并将其应用于正确的API。
我还没有对此进行测试,但一个可能的问题是您正在覆盖$作用域上的对象。这可以打破双向绑定。要进行快速测试,请键入
$scope.grid = {
Options: {
data: 'myData',
enablePaging: true,
showFooter:true,
totalServerItems: 'totalServerItems',
pagingOptions: $scope.pagingOptions,
filterOptions: $scope.filterOptions,
enableCellEdit: true,
enableColumnReordering: true,
enablePinning: true,
showGroupPanel: true,
groupsCollapsedByDefault: true,
enableColumnResize: true
}
}
$scope.grid.Options = GridOptionsService.getGridOptions('documents');
你当然也需要更新指令属性中的网格选项
问题是用于过滤和分页的控制器函数使用控制器$scope
上定义的选项,但是ng-grid UI没有绑定到这些对象。
过滤和分页的控制器方法使用$scope.pagingOptions
作为数据源。但是,ng-grid UI绑定到$scope.gridOptions.pagingOptions
。当您在控制器中显式地创建$scope.gridOptions
时,$scope.gridOptions.pagingOptions
引用与$scope.gridOptions
相同的对象,因此在UI中进行更改将更改控制器函数中使用的值。
但是,当业务分配$scope.gridOptions
时,业务正在创建新的pagingOptions
,因此$scope.gridOptions.pagingOptions
和$scope.pagingOptions
之间没有连接。修改UI不会改变控制器函数中使用的值。
对于filterOptions
也是如此。
解决这个问题的一个方法是
$scope.gridOptions = GridOptionsService.getGridOptions('documents');
$scope.pagingOptions = $scope.gridOptions.pagingOptions
$scope.filterOptions = $scope.gridOptions.filterOptions
- 音频控件在mouseover上显示,在mouseout上淡出
- 后焦点更改为IE 11中的地址栏,而不是转移到表单中的下一个控件
- 如何在读取XLS/XLSX本地文件时,使用IE的javascript代码启用未标记为安全的ActiveX控件
- Windows形成web浏览器控件和Javascript更改的DOM
- 如何将javascript事件从web浏览器wpf控件发送到wpf的c#代码
- 如何更改文本框控件的不透明度值
- 所有控件的组合框
- 如何使用ngModel将自定义控件的提供程序扩展器分离到Angular 2中的单独文件中
- 如何使用angular js验证器执行下拉控件验证
- 将Angular.JS与onsenui一起使用时,控件不可见
- 将控件转换为Angular指令
- 在wix的angular树控件中,如何展开默认情况下页面加载上有子节点的所有节点
- Angular 2 -自定义表单控件-禁用
- Angular控件在最小化JS文件后不起作用
- Angular 2引用了验证消息的控件
- Angular -表单控件ngPattern来检查字母和数字
- 如何从angular变量中拆分字符串值,并将其设置为两个html控件
- 当配置选项来自service时,Angular中的控件会中断
- Angular js, on ng-change如何更新其他select控件的选项
- Angular Js :访问指令中的数据并创建表单控件