角度视图未使用新数据更新

时间:2015-04-19 15:56:20

标签: javascript angularjs angularjs-scope angularjs-ng-repeat angularjs-routing

我是一个角色新手,如果这很明显就很抱歉。

我有一个返回一个对象数组的后端。在我检索它们之后,我移动到下一页,我需要为每个对象显示一个复选框。我可以成功检索它们,因此我将浏览器的位置更改为应显示复选框但未显示任何内容的下一页。我尝试使用$ scope。$ apply()但它会抛出一个错误,说明摘要已经发生但我认为这是正确的,因为我使用了包含在$ scope中的ng-click。$ apply()我认为?

我可以在控制台中看到正在打印的服务,但它们不会出现在页面中。不确定我在这里做错了什么?

在我的首发视图中:

<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>

在我的控制器中:     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")
        });
};

})

在我的服务部分:

<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>

我的服务服务(坏名称):

angular.module('servicesService', [])

.factory('Service', function($http) {

    return {
        getServices : function(tag) {
            return $http.get('/api/service?searchTerm='+tag)
        }
    }
});

我的应用配置:

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('}]}');

    }
]);

我正在使用{[{}}}进行插值,否则会使用Blade语法

进行分类

3 个答案:

答案 0 :(得分:4)

您位于angular范围内,因此无需触发$scope.$apply()。只有当你超出角度范围时才需要它。

  

关于您的问题:

您将在服务中返回promise对象。因此返回的数据仅在该控制器中可用。如果您要转到下一页,那么该数据将无法使用。

如果要共享数据,则必须将其存储在服务中。

在您的服务中:

 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;
        }
    }
});

现在,在另一个控制器中,您可以使用getData()

访问数据

在您的控制器中,您可能需要稍微修改一下:

$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();
        });
};

在第二个控制器中,您可以通过Service.getData()

访问它

由于您对两个视图使用相同的控制器,因此需要使用if条件来检查route并单独获取数据。否则,您最终可能会再次拨打服务电话。

答案 1 :(得分:1)

即使两条路线都有相同的控制器名称,也不代表它们是相同的。

它们就像是同一个类的两个独立实例,每个实例的数据总是不同的。因此将其设置在一个地方并在另一个地方使用它不是可行的方法。

您需要的是在控制器之间共享数据的服务

只是为了详细说明评论......您可以使用服务在控制器之间共享数据。看看this video from egghead.io

egghead.io是开始使用angualrjs的绝佳资源。

这就是该服务应该是什么样子

app.service('productService', function() {
  var personList = [];

  var add = function(newObj) {
      personList.push(newObj);
  }

  var get = function(){
      return personList;
  }

  return {
    add: add,
    get: get
  };

});

以上是我在应用程序中如何在控制器之间共享数据的简化示例

答案 2 :(得分:0)

我认为你没有使用相同的ng-model,请仔细检查你的ng-contoller标签。你的意思是2

试试这个

if (!$scope.$$phase)
    $scope.$apply();