Представление не обновляется после асинхронного вызова $ http при использовании синтаксиса controllerAs

0

Я изучаю angularjs, и я пытаюсь использовать синтаксис controllerAs, как я из фона Java, и это будет иметь для меня больше смысла, но мне трудно понять цикл дайджеста.

Я пытаюсь сделать http-вызов и обновить переменную в контроллере. Когда я использую $ scope в контроллере, представление обновляется после получения данных, но когда я использую синтаксис controllerAs, представление не обновляется.

Синтаксис Codepen с $ scope

http://codepen.io/eternal15/pen/BzANEw?editors=1111

  <html>
  <head>
        <script src="/angular.min.js"></script>
  </head>
  <body ng-app="Test" ng-controller="testCtrl">
    {{output}}
    <button ng-click="onClick()">Test</button>
  </body>

</html>
//JS FILE
angular.module("Test", []).controller('testCtrl', ['$scope','$http', function($scope, $http){
  $scope.output = "Loading";
  $scope.onClick = function(){
    console.log('clicked');
    $http.get('http://jsonplaceholder.typicode.com/posts').then(function(data){ 
      $scope.output = "worked!!";
      console.log($scope.output);
    })
  }
}]);

Codepen с контроллером. Синтаксис (просмотр не обновлен)

http://codepen.io/eternal15/pen/yJKoaZ?editors=1011

<html>
  <head>
        <script src="/angular.min.js"></script>
  </head>
  <body ng-app="Test" ng-controller="testCtrl as test">
    {{test.output}}
    <button ng-click="test.onClick()">Test</button>
  </body>

</html>
//JS File
angular.module("Test", []).controller('testCtrl', ['$http', function($http){
  this.output = "Loading";
  this.onClick = function(){
    console.log('clicked');
    $http.get('http://jsonplaceholder.typicode.com/posts').then(function(data){ 
      this.output = "worked!!";
      console.log(this.output);
    })
  }
}]);

Я прочитал о синтаксисе controllerAs, и я думаю, что он добавит объект (тест в примере выше) под область видимости и, следовательно, переменные будут доступны с использованием (тестового) объекта.

Итак, цикл digest выполняется после вызова $ http, потому что представление обновляется в первом примере с использованием $ scope. Так как цикл дайджеста выполняется, то объектный тест во втором примере также должен быть обновлен правильно?

Также я попытался ввести $ scope и сделать $ scope. $ Apply(), и это тоже не сработало, и это дало мне эту ошибку

Error: [$rootScope:inprog] http://errors.angularjs.org/1.5.2/$rootScope/inprog?p0=%24digest

Я хотел бы знать, что я делаю неправильно. Хотя я мог бы вернуться к использованию формата $ scope, мне бы хотелось знать, что я делаю что-то неправильно или мне нужно добавить другие инструкции для просмотра переменных и обновления значений вручную.

заранее спасибо

Теги:

2 ответа

2
Лучший ответ

this имеет другое значение внутри функции. Назначьте this переменной и используйте ее. Пытаться:

angular.module("Test", []).controller('testCtrl', ['$http', function($http){
  var vm = this;
  vm.output = "Loading";
  vm.onClick = function(){
    console.log('clicked');
    $http.get('http://jsonplaceholder.typicode.com/posts').then(function(data){ 
      vm.output = "worked!!";
      console.log(vm.output);
    })
  }
}]);
  • 0
    Спасибо. Это сработало
1

Это связано с закрытием javascripts. При определении новой функции вы создаете новую область, следовательно, ключевое слово this имеет новое значение для каждого нового объема.

Чтобы решить эту проблему, определите область контроллеров в верхней части вашего контроллера. Обычными именами являются либо vm либо $ctrl.

Тогда ваш контроллер будет выглядеть следующим образом:

angular.module("Test", []).controller('testCtrl', ['$http', function( $http){
  var $ctrl = this;
  $ctrl.output = "Loading";
  $ctrl.onClick = function(){
    console.log('clicked');
    $http.get('http://jsonplaceholder.typicode.com/posts').then(function(data){ 
      $ctrl.output = "worked!!";
      //$scope.$apply();
    })
  }
}]);
  • 0
    Спасибо за ответ. Это сработало

Ещё вопросы

Сообщество Overcoder
Наверх
Меню