在我的AngularJS项目中,我有一个uint16_t
HTML元素,应该与巴西的州绑定。所以,我正在使用ng-repeat来填充使用RESTful API从我的项目数据库加载的状态。
然后,在我的控制器中,我在名为select
的范围上创建了一个变量,并为它设置了一个空数组[1]。在我调用$ http.get [2]之后,我从基数接收数据,并将其设置为$ scope.estados [3],用于ng-repeat。 [4]
控制器代码:
estados
HTML code:
myApp.controller('myCtrl', function($scope, $http, API_URL) {
$scope.estados = []; //[1]
$http({ // [2]
method: 'GET',
url:API_URL + '/estados',
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
}).then(function(response) {
if(response.status == 200){
$scope.estados = response.data; // [3]
console.log($scope.estados);
}
});
});
但是,ng-repeat不会使用新值更新。当我在<select name="uf" class="form-control" ng-model="Empresa.endereco.estado_uf">
<option ng-repeat="estado in estados" ng-value="estado.uf"> {{estado.nome}}</option> <!-- [4] -->
</select>
的成功函数中调用de console.log($scope.estados);
时,我可以看到$ scope使用正确的值更新,但它不会传递给View。
在设置$ scope.estados之后我已经尝试调用$http.get.then()
,但我抛出错误:$scope.$apply();
。
如果我使用另一个值对该变量进行实例化,则绑定它,如下所示:
[$rootScope:inprog] $digest already in progress
但它永远不会更新数据库值。 我究竟做错了什么?我似乎喜欢与引用有关的东西,但我不确切知道是什么。
答案 0 :(得分:2)
我有2条建议。
首先 - 不要将您的数据分配到$scope
变量(对于某些上下文,请对“点规则”进行快速Google搜索)。而是将其分配给控制器代码中带有this.estados = data
的控制器变量,然后使用ControllerAs变量在DOM中访问它...例如:
ng-controller="myCtrl as myCtrl"
然后在DOM myCtrl.estados
中而不是$scope.estados
注意:在$http
回调函数中,this
将不再引用Controller。您需要在Controller代码的正文中存储this
的引用,以便稍后引用它。我倾向于在我的所有Controller代码的顶部使用var controller = this;
,因此可以在任何返回函数中轻松访问它。
第二次 ...为您的选择使用ng-options而不是转发器。它更强大,并确保正确的数据绑定。所以在你的实例中:
<select ... ng-options="estado.uf as estado.name for estado in myCtrl.estados"></select>
上面的...
旨在引用select
元素中您需要的任何内容,例如ng-model
,class
等。
我怀疑只是转换为Dot符号而不是使用$scope
可以解决这种情况......像ng-if
和ng-switch
这样的指令(将元素从DOM中拉出来的任何东西)都可以使$scope
变量无法在某种程度上无法预测。使用ng-options
总是更好的做法IMO。
答案 1 :(得分:0)
我还无法测试,但如果更换引用,ngRepeat
常常失去跟踪数组的功能。哪个控制器发生了什么。
您可以做的快速测试是编辑控制器以保持对同一数组的引用,并通过循环并将新结果添加到已绑定的数组来操作它。
myApp.controller('myCtrl', function($scope, $http, API_URL) {
$scope.estados = []; //[1]
$http({ // [2]
method: 'GET',
url:API_URL + '/estados',
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
}).then(function(response) {
if(response.status == 200){
$scope.estados.length = 0; // truncate array
for(var state in response.data)
$scope.estados.push(state); // [3]
console.log($scope.estados);
}
});
});
答案 2 :(得分:0)
您可以尝试两项更改:
1)明确设置轨道通常可以帮助ng-repeat刷新元素(即使默认情况下它已经是track by $index
):
ng-repeat="estado in estados`track by $index"
2)而不是将数组分配给新数组,只需concat
结果到当前空数组:
$scope.estados.concat(response.data);
答案 3 :(得分:0)
这已在许多链接中讨论过。
实际上我们应该只使用范围内的对象。原始值不会反映在消化周期中。
建议使用范围内的对象。
$scope.object= {};
$scope.object.estados = [];
$scope.object.estados = response.data;
HTML:
<select name="uf" class="form-control" ngmodel="Empresa.endereco.estado_uf">
<option ng-repeat="estado in object.estados" ng-value="estado.uf">
{{estado.nome}}</option>
</select>
请阅读以下链接。
https://github.com/angular/angular.js/wiki/Understanding-Scopes