问题
I'm a bit of an Angular newbie so sorry if this is obvious.
I have a backend which returns an array of objects. After I retrieve them, I move to the next page and i need to display a checkbox for each of the objects. I can successfully retrieve them, so I change the location of browser to the next page where the checkboxes should be displayed but nothing is being displayed. I tried using $scope.$apply() however it throws an error stating that a digest is already taking place but I think that's correct because I've used ng-click which is wrapped in a $scope.$apply() I think?
I can see the services being printed out in the console successfully, however they don't appear in the page. Not sure what I'm doing wrong here?
In my starting view:
<form>
<div class="form-group">
<select id="main_service" name="main_service" class="form-control" ng-model="mainService">
<option>Please Select...</option>
<option ng-repeat="service in mainServices" value="{[{service}]}">{[{service}]}</option>
</select>
</div>
<div class="form-group">
<button class="btn btn-primary" type="submit" ng-click="updateServices()">Continue</button>
</div>
</form>
in my controller: var professionalSignupControllers = angular.module('professionalSignupCtrls', [])
professionalSignupControllers.controller('professionalQuestions', function($scope, $http, Service, $sce, $routeParams,$location){
$scope.mainService = "";
$scope.services = [];
$scope.updateServices = function(){
Service.getServices($scope.mainService)
.success(function(data) {
$scope.services = data
console.log($scope.services)
//$scope.$apply(); throws digest error!
$location.path( '/services' );
})
.error(function(data, error) {
event.preventDefault();
alert("Oh Dear")
});
};
})
In my services partial:
<div>
<div ng-repeat="service in services" class="checkbox">
<label><input type="checkbox" name="service[]" value="{[{service.id}]}" ng-model="user.services">{[{service.label}]}</label>
</div>
</div>
My servicesService (bad name):
angular.module('servicesService', [])
.factory('Service', function($http) {
return {
getServices : function(tag) {
return $http.get('/api/service?searchTerm='+tag)
}
}
});
My app config:
app.config(['$routeProvider', '$locationProvider','$interpolateProvider',
function($routeProvider,$locationProvider,$interpolateProvider) {
$routeProvider.
when('/start', {
templateUrl: '/js/partials/start-professional-questions.html',
controller: 'professionalQuestions'
}).
when('/services', {
templateUrl: '/js/partials/services-professional-questions.html',
controller: 'professionalQuestions'
}).
otherwise({
redirectTo: '/start'
});
$interpolateProvider.startSymbol('{[{').endSymbol('}]}');
}
]);
I'm using {[{ }]} for interpolation as otherwise it would class with the Blade syntax
回答1:
You're in angular
scope and so you need not trigger $scope.$apply()
. it's required only when you're out of angular scope.
Regarding your issue:
You're returning the promise object in the service. So the data returned is only available in that controller alone. If you're moving to next page then that dat won't be available.
If you want to share the data, then you must store that inside the service.
In your service:
angular.module('servicesService', [])
.factory('Service', function($http, $q) {
var data;
return {
getData: function() {
return data;
},
getServices : function(tag) {
var defer = $q.defer();
$http.get('/api/service?searchTerm='+tag).then(function(response) {
data = response;
defer.resolve(response);
});
return defer.promise;
}
}
});
Now in your another controller, you can access the data using getData()
In your controller, you may need to modify it a bit:
$scope.updateServices = function(){
Service.getServices($scope.mainService).then(function(data){
$scope.services = data
console.log($scope.services)
$location.path( '/services' );
}, function(data, error) {
event.preventDefault();
});
};
In your second controller, you can access it via Service.getData()
Since you're using same controller for both views, you need to use an if
condition to check the route
and get the data alone. Else you may end up firing the service call again.
回答2:
even if both the routes have same controller name, it does not mean that they are same..
its like they are two separate instances of same class, and data for each instance would always be different. hence setting it at one place and using it at another is not the way to go.
What you need is a service to share data between controllers
just to elaborate the comment... you can use services to share data between controllers. check out this video from egghead.io
egghead.io is an excellent resource for starting with angualrjs.
this is how that service should look like
app.service('productService', function() {
var personList = [];
var add = function(newObj) {
personList.push(newObj);
}
var get = function(){
return personList;
}
return {
add: add,
get: get
};
});
above is an simpilified example of how I share data between controllers in my application
回答3:
I think you haven't use the same ng-model,double check you your ng-contoller tag.And you meant 2
Try this
if (!$scope.$$phase)
$scope.$apply();
来源:https://stackoverflow.com/questions/29732153/angular-view-not-updating-with-new-data