AngularJS:通过AJAX配置ng-model后无法获取下拉选中值求助
我现在遇到一个问题:通过AJAX获取数据渲染的下拉菜单可以正常显示,但选中选项后用ng-model获取值时结果总是null。推测是设置ng-model的方式有问题,以下是我的代码:
HTML代码
<select id="countryListId"></select>
AngularJS控制器代码
$scope.fetchCountries = function() { var $selectCountry = $('#countryListId'); $.ajax( { url: 'http://.../someurl/dropdown?typ=Countries', dataType: 'JSON', success: function(data) { $selectCountry.html('<select ng-model="locationForm.country"></select>'); $.each(data, function(key, val) { $selectCountry.append('<option value="' + val.code + '">' + val.value + '</option>'); }) }, error: function() { $selectCountry.html('<option id="-1">none available</option>'); } }); }
当前下拉菜单能正常渲染接口返回的数据,但选中后locationForm.country始终是null,想请教如何正确配置ng-model,或者有没有其他可靠的方式获取选中值?
嘿,我来帮你捋清楚这个问题——你用jQuery直接修改DOM的方式,和AngularJS的双向绑定机制根本不兼容。Angular需要先编译DOM元素才能识别ng-model这类指令,而你通过jQuery插进去的<select ng-model="locationForm.country">完全没经过Angular的处理,所以双向绑定压根没生效,自然拿不到值。
下面给你两种可行的解决办法,优先推荐第一种,更符合Angular的设计思路:
方法一:用Angular原生方式实现(强烈推荐)
别再用jQuery的$.ajax和DOM操作了,换成Angular自带的$http服务拿数据,配合ng-options渲染下拉菜单,这样双向绑定会自动生效:
修改后的HTML
<select ng-model="locationForm.country" ng-options="country.code as country.value for country in countries"> <option value="">请选择国家</option> </select>
修改后的控制器代码
// 先初始化好需要的变量 $scope.countries = []; $scope.locationForm = { country: null }; $scope.fetchCountries = function() { // 用Angular的$http发请求 $http.get('http://.../someurl/dropdown?typ=Countries') .then(function(response) { // 把接口返回的数据赋值给$scope,Angular会自动更新视图 $scope.countries = response.data; }, function() { // 请求失败时的处理,比如设置默认选项 $scope.countries = [{ code: '-1', value: 'none available' }]; }); }
这样改完之后,你选中任何选项,$scope.locationForm.country都会立刻拿到对应的code值,完全不用手动操作DOM,省心多了。
方法二:如果必须保留jQuery操作(不推荐)
要是因为某些特殊情况,你非得用jQuery来搞DOM,那得手动让Angular编译你动态插入的元素,还要触发它的更新循环:
修改后的控制器代码
// 注意要在控制器里注入$compile服务 app.controller('YourController', ['$scope', '$compile', function($scope, $compile) { $scope.locationForm = { country: null }; $scope.fetchCountries = function() { var $selectCountry = $('#countryListId'); $.ajax( { url: 'http://.../someurl/dropdown?typ=Countries', dataType: 'JSON', success: function(data) { $selectCountry.empty(); // 创建带ng-model的select元素 var selectElement = $('<select ng-model="locationForm.country"></select>'); $selectCountry.append(selectElement); // 关键:用$compile编译这个元素,让Angular识别ng-model指令 $compile(selectElement)($scope); // 循环添加选项 $.each(data, function(key, val) { selectElement.append('<option value="' + val.code + '">' + val.value + '</option>'); }); // 手动触发Angular的digest循环,更新绑定 $scope.$apply(); }, error: function() { $selectCountry.html('<option value="-1">none available</option>'); } }); } }]);
不过这种方式相当于把Angular和jQuery混着用,很容易出各种难以排查的问题,除非万不得已,真的不建议这么做。
内容的提问来源于stack exchange,提问作者Sikandar Sahab

