Angular View Not Updating with New Data

风格不统一 提交于 2019-12-10 21:08:52

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!