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'];