我在Angular SPA中遇到问题,当重新加载视图时,select
正在丢失所选项目。所选项目值是正确的。这是一个典型的搜索/结果场景,所以我必须遗漏一些基本的东西。
角度模块(这里很简洁)设置了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>
在视图中,选择值由data-ng-init="init()"
填充,input
框和select
下拉列表绑定到同一模型项ng-model="searchQuery.categoryID"
。
在选择类别后加载视图时会发生什么,该值是丢失的,并且选择将恢复为“任何”。文本框具有正确的选定值。我确认select
已绑定到模型元素,因为更改input
中的值会更改select
中的所选项目。在重新加载时,我可以看到select
闪烁,看起来它有一段时间的选定值然后丢失它。
修改:总之,所选类别仅作为select
中的所选项目“丢失”。所选类别值在网址和input
文本框中正确显示。这不是参考比较问题,因为选择选项值为item.CategoryID
而不是item
类别对象。
我在这里做错了什么?如何将select
与绑定值分离和/或我设置绑定错误?
顺便说一句,我还尝试ng-options
代替ng-repeat
来设置select
,但在这种情况下,更改input
中的值没有任何影响。
答案 0 :(得分:1)
此问题实际上是$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'];