问题
I am making my first project using Angularjs 1.4.3.
In my controller I am making a http request, in the success method of this http request I am updating a scope variable. In http call I am getting the latest values but in the view side its not updating the values.
Plunker Link (@rupesh_padhye thanks). (Since it is calling the servlet action, so no data will be shown in Plunker)
app.controller('measuresCtrl', ['$scope', '$modal', '$http', function($scope, $modal, $http) {
$scope.groups = []
$scope.loadAllMeasure = function() {
$http.get("fetchAllMeasure")
.success(function(data) {
console.log("Before insert");
console.log($scope.groups);
$scope.groups = data.measures;
console.log("After insert");
console.log($scope.groups);
})
.error(function() {
});
};
$scope.loadAllMeasure();
$scope.submit = function (form) {
$http({
method: 'POST',
url: 'saveMeasure',
data: {
id: form.id,
name: form.name,
description: form.description
},
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
}).success(function(data, status, headers, config) {
$scope.loadAllMeasure();
}).error(function(data, status, headers, config) {
});
}
})
And whenever I am performing any CRUD operation on measures I am calling a method $scope.loadAllMeasure();
. But its not updating the values in the view (jsp) page.
I have tried $scope.$apply method but I am getting Error: $digest already in progress
.
When I printed the value for $scope.groups using console.log inside success method, then its showing the latest values.
In my view (jsp) page I am just using ng-repeat function to show all the records in table format.
Code for my view page (minimal code) -
<div ng-repeat="group in groups | orderBy:'name'">
<div>
<input type="checkbox" id="checkbox-{{group.id}}" class="ui-checkbox" /><label for="checkbox-{{group.id}}">{{group.name}}</label>
</div>
<div>{{ group.description}}</div>
<div>
<div class="fa fa-pencil button" data="{{group.id}}" id="{{::elementId}}" ng-click="showEditForm(group.id, $event)"></div>
<div class="fa fa-trash button" data="{{group.id}}" ng-click="deleteGroup(group.id)"></div>
<div class="fa fa-clone button" data="{{group.id}}" id="{{::elementId}}" ng-click="showCloneForm(group.id, $event)"></div>
</div>
</div>
Values in console.log are
Before insert
Object { id=1, description="Measure Description1", name="Demo"}]
And
After Insert
[Object { id=1, description="Measure Description1", name="Demo"}, Object { id=2, description="Description2", name="Demo2"}]
How to update scope variable value in view after http call?
回答1:
I cant see anything wrong with your example code.
I have created a JSFiddle to try and help you.
The server call has been replaced by a setTimeout function that returns a promise.
Please see JSFiddle https://jsfiddle.net/sjwkbzxa/
Please see example below:
<div data-ng-controller="TestController as vm">
<button data-ng-click="loadAllMeasure()">Load List from Server</button>
<ul>
<li data-ng-repeat="group in groups | orderBy:'name'">
<span>{{group.description}}</span>
</li>
</ul>
</div>
The javascript:
angular.module('application',[]).controller("TestController", ['$scope', '$q', function($scope, $q){
$scope.groups = [{ id:1, description:"Initial List", name:"Demo"}];
$scope.loadAllMeasure = function(){
loadData().then(function(data){
$scope.groups = data;
});
};
function loadData(){
var deferred = $q.defer();
setTimeout(function(){
var data = [{ id:1, description:"Measure Description1", name:"Demo"}, { id:2, description:"Description2", name:"Demo2"}];
deferred.resolve(data);
}, 3000);
return deferred.promise;
}
}]);
Maybe you are missing something on your side that we cant see?
回答2:
After assigning the new data to a $scope variable call:
$scope.$digest();
This will update the current scopes values
reference here: https://docs.angularjs.org/api/ng/type/$rootScope.Scope
回答3:
I'm a little late to answer this, but here are my 2 cents:
A simple assignment of the server data (response.data) to a $scope object didnt seem to work for me
$scope.something = response.data //didn't work
So, I returned a promise object from the service into the controller and then use
angular.copy(response.data,$scope.something)
to copy the values returned from the server. You could also pass the $scope.something to the service as a parameter to the function and have angular.copy in the service function as well, but i don't know if it's a good practise to do that.
回答4:
$scope.loadAllMeasure = function() {
CalltoServer();
};
CalltoServer = function() {
return $http.get("fetchAllMeasure")
.success(function(data) {
$scope.groups = data.measures;
})
.error(function() {
});
}
try this , the success will be after 2 or 3 seconds so i guess inside the event it takes rist to bind
回答5:
Hey I also faced the same issue and if anyone is still looking, it is caused by change in the $scope variable inside the $http. I think a new $scope is being created inside the success function(some prototypical inheritance stuff). So make a copy of the variable $scope, something like
var s = $scope;
and then change
s.groups = someData;
Your code:
app.controller('measuresCtrl', ['$scope', '$modal', '$http', function($scope, $modal, $http) {
var s = $scope;
$scope.groups = []
$scope.loadAllMeasure = function() {
$http.get("fetchAllMeasure")
.success(function(data) {
console.log("Before insert");
console.log($scope.groups);
s.groups = data.measures;
console.log("After insert");
console.log($scope.groups);
})
.error(function() {
});
};
$scope.loadAllMeasure();
$scope.submit = function (form) {
$http({
method: 'POST',
url: 'saveMeasure',
data: {
id: form.id,
name: form.name,
description: form.description
},
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
}).success(function(data, status, headers, config) {
$scope.loadAllMeasure();
}).error(function(data, status, headers, config) {
});
}
})
来源:https://stackoverflow.com/questions/34017376/how-to-update-scope-variable-value-in-view-after-http-call