AngularJS 在视图重新加载时丢失所选项目(参数的数据类型丢失)
AngularJS Loses Selected Item on View Reload (data type of parameter lost)
我 运行 遇到 Angular SPA 中的一个问题,其中 select
在重新加载视图时丢失 selected 项目。 selected 项目值是正确的。这是一个典型的 search/results 场景,所以我肯定遗漏了一些基本的东西。
angular 模块(此处压缩很多)设置了 ui 路由和状态,它们决定了要加载的视图和控制器等:
var DomainApp = angular.module('DomainApp', ['ui.router', 'ui.bootstrap', 'angularValidator']);
// add controllers, services, and factories
DomainApp.controller('ProductsController', ProductsController);
DomainApp.service('ProductsService', ProductsService);
var configFunction = function ($stateProvider, $httpProvider, $locationProvider) {
$stateProvider
.state('productSearch', {
url: '/products',
views: {
"searchView": {
templateUrl: '/Templates/products/Search.html',
controller: ProductsController
}
}
})
.state('productResults', {
url: '/products/Results?categoryID',
views: {
"searchView": {
templateUrl: '/Templates/products/Search.html',
controller: ProductsController
}
}
})
}
configFunction.$inject = ['$stateProvider', '$httpProvider', '$locationProvider'];
DomainApp.config(configFunction);
产品管理员:
var ProductsController = function($scope, $stateParams, $state, $location, ProductsService) {
// data for search operations
$scope.searchQuery = {
categoryID: $stateParams.categoryID || 0,
categories: null
};
// init api
$scope.init = function () {
var categoryResult = ProductsService.getCategories(0);
categoryResult.then(function(result) {
if (result.isSuccess) {
$scope.searchQuery.categories = result.data.Items;
} else {
$scope.status.isError = true;
$scope.status.errorMessage = result.message;
}
});
}
}
ProductsController.$inject = ['$scope', '$stateParams', '$state', '$location', 'ProductsService'];
产品服务:
var ProductsService = function ($http, $q) {
this.getCategories = function (categoryID) {
var deferredObject = $q.defer();
var results = {
isSuccess: true,
message: '',
data: null
}
$http.get('/api/categories/list/100' + ',' + categoryID).
success(function (data) {
results.data = data;
deferredObject.resolve(results);
}).
error(function (data, status, headers, config) {
results.isSuccess = false;
results.message = 'Could not get Category list:';
for (var i = 0; i < data.length; i++) {
results.message = results.message + ' ' + data[i].Message;
}
deferredObject.resolve(results);
});
return deferredObject.promise;
};
}
ProductsService.$inject = ['$http', '$q'];
以及产品搜索模板(视图):
<div class="container-fluid searchbar" data-ng-init="init()">
<h2>Product Search</h2>
<div class="row top5">
<div class="col-md-5">
<label for="category">Category:</label><input type="text" class="form-control" maxlength="40" id="categoryID" ng-model="searchQuery.categoryID" />
<select class="form-control" name="category" ng-model="searchQuery.categoryID">
<option value="0">Any</option>
<option ng-repeat="item in searchQuery.categories" value="{{item.CategoryID}}">{{item.CategoryName}}</option>
</select>
</div>
</div>
<div class="row top15">
<div class="col-md-12">
<a class="btn btn-default" ui-sref="productResults({categoryID: searchQuery.categoryID})">Search</a>
</div>
</div>
</div>
在视图中,select 值由 data-ng-init="init()"
填充,input
框和 select
下拉列表绑定到同一模型项 ng-model="searchQuery.categoryID"
.
在 select 类别之后加载视图时会发生什么情况,即值丢失,并且 selection 恢复为 "Any"。文本框具有正确的 selected 值。我验证了 select
绑定到模型元素,因为更改 input
中的值会更改 select
中的 selected 项目。重新加载时,我可以看到 select
闪烁,看起来它有片刻的 selected 值然后丢失。
编辑:综上所述,selected 类别仅 "lost" 作为 select
中的 selected 项目]. selected 类别值正确显示在 url 和 input
文本框中。这不是参考比较问题,因为 select 选项值是 item.CategoryID
而不是 item
类别对象。
我在这里做错了什么? select
如何与绑定值分离 and/or 我是不是设置了绑定错误?
顺便说一下,我也尝试过 ng-options
而不是 ng-repeat
来设置 select
,但在那种情况下更改 input
中的值没有任何影响。
这个问题其实是$stateParams
中的一个bug,整型的数据类型丢失了,变成了字符串。这个问题应该在 Angular UI 路由器的 0.2.12 版本中得到修复,但我仍然在 0.2.13 中看到这个问题并且必须通过将参数值转换回数.
具有Number
功能的更新产品控制器:
var ProductsController = function($scope, $stateParams, $state, $location, ProductsService) {
// data for search operations
$scope.searchQuery = {
categoryID: Number($stateParams.categoryID) || 0,
categories: null
};
// init api
$scope.init = function () {
var categoryResult = ProductsService.getCategories(0);
categoryResult.then(function(result) {
if (result.isSuccess) {
$scope.searchQuery.categories = result.data.Items;
} else {
$scope.status.isError = true;
$scope.status.errorMessage = result.message;
}
});
}
}
ProductsController.$inject = ['$scope', '$stateParams', '$state', '$location', 'ProductsService'];
我 运行 遇到 Angular SPA 中的一个问题,其中 select
在重新加载视图时丢失 selected 项目。 selected 项目值是正确的。这是一个典型的 search/results 场景,所以我肯定遗漏了一些基本的东西。
angular 模块(此处压缩很多)设置了 ui 路由和状态,它们决定了要加载的视图和控制器等:
var DomainApp = angular.module('DomainApp', ['ui.router', 'ui.bootstrap', 'angularValidator']);
// add controllers, services, and factories
DomainApp.controller('ProductsController', ProductsController);
DomainApp.service('ProductsService', ProductsService);
var configFunction = function ($stateProvider, $httpProvider, $locationProvider) {
$stateProvider
.state('productSearch', {
url: '/products',
views: {
"searchView": {
templateUrl: '/Templates/products/Search.html',
controller: ProductsController
}
}
})
.state('productResults', {
url: '/products/Results?categoryID',
views: {
"searchView": {
templateUrl: '/Templates/products/Search.html',
controller: ProductsController
}
}
})
}
configFunction.$inject = ['$stateProvider', '$httpProvider', '$locationProvider'];
DomainApp.config(configFunction);
产品管理员:
var ProductsController = function($scope, $stateParams, $state, $location, ProductsService) {
// data for search operations
$scope.searchQuery = {
categoryID: $stateParams.categoryID || 0,
categories: null
};
// init api
$scope.init = function () {
var categoryResult = ProductsService.getCategories(0);
categoryResult.then(function(result) {
if (result.isSuccess) {
$scope.searchQuery.categories = result.data.Items;
} else {
$scope.status.isError = true;
$scope.status.errorMessage = result.message;
}
});
}
}
ProductsController.$inject = ['$scope', '$stateParams', '$state', '$location', 'ProductsService'];
产品服务:
var ProductsService = function ($http, $q) {
this.getCategories = function (categoryID) {
var deferredObject = $q.defer();
var results = {
isSuccess: true,
message: '',
data: null
}
$http.get('/api/categories/list/100' + ',' + categoryID).
success(function (data) {
results.data = data;
deferredObject.resolve(results);
}).
error(function (data, status, headers, config) {
results.isSuccess = false;
results.message = 'Could not get Category list:';
for (var i = 0; i < data.length; i++) {
results.message = results.message + ' ' + data[i].Message;
}
deferredObject.resolve(results);
});
return deferredObject.promise;
};
}
ProductsService.$inject = ['$http', '$q'];
以及产品搜索模板(视图):
<div class="container-fluid searchbar" data-ng-init="init()">
<h2>Product Search</h2>
<div class="row top5">
<div class="col-md-5">
<label for="category">Category:</label><input type="text" class="form-control" maxlength="40" id="categoryID" ng-model="searchQuery.categoryID" />
<select class="form-control" name="category" ng-model="searchQuery.categoryID">
<option value="0">Any</option>
<option ng-repeat="item in searchQuery.categories" value="{{item.CategoryID}}">{{item.CategoryName}}</option>
</select>
</div>
</div>
<div class="row top15">
<div class="col-md-12">
<a class="btn btn-default" ui-sref="productResults({categoryID: searchQuery.categoryID})">Search</a>
</div>
</div>
</div>
在视图中,select 值由 data-ng-init="init()"
填充,input
框和 select
下拉列表绑定到同一模型项 ng-model="searchQuery.categoryID"
.
在 select 类别之后加载视图时会发生什么情况,即值丢失,并且 selection 恢复为 "Any"。文本框具有正确的 selected 值。我验证了 select
绑定到模型元素,因为更改 input
中的值会更改 select
中的 selected 项目。重新加载时,我可以看到 select
闪烁,看起来它有片刻的 selected 值然后丢失。
编辑:综上所述,selected 类别仅 "lost" 作为 select
中的 selected 项目]. selected 类别值正确显示在 url 和 input
文本框中。这不是参考比较问题,因为 select 选项值是 item.CategoryID
而不是 item
类别对象。
我在这里做错了什么? select
如何与绑定值分离 and/or 我是不是设置了绑定错误?
顺便说一下,我也尝试过 ng-options
而不是 ng-repeat
来设置 select
,但在那种情况下更改 input
中的值没有任何影响。
这个问题其实是$stateParams
中的一个bug,整型的数据类型丢失了,变成了字符串。这个问题应该在 Angular UI 路由器的 0.2.12 版本中得到修复,但我仍然在 0.2.13 中看到这个问题并且必须通过将参数值转换回数.
具有Number
功能的更新产品控制器:
var ProductsController = function($scope, $stateParams, $state, $location, ProductsService) {
// data for search operations
$scope.searchQuery = {
categoryID: Number($stateParams.categoryID) || 0,
categories: null
};
// init api
$scope.init = function () {
var categoryResult = ProductsService.getCategories(0);
categoryResult.then(function(result) {
if (result.isSuccess) {
$scope.searchQuery.categories = result.data.Items;
} else {
$scope.status.isError = true;
$scope.status.errorMessage = result.message;
}
});
}
}
ProductsController.$inject = ['$scope', '$stateParams', '$state', '$location', 'ProductsService'];