2015-05-29 1 views
1

Я не могу разобраться в проблеме здесь. При ответе на успех ajax я устанавливаю значение в текущем контроллере, который не отражается в пользовательском интерфейсе. Общий ответ, который я нашел, заключается в том, чтобы работать с функциями Angular ajax и/или применять $ apply или $ digest к области $. Ни одно из них не работает.

Обратите внимание, что в коде {{и}} угловые метки заменяются <% и%>, поскольку я использую механизм заклинивания лезвия, и эти теги конфликтуют.

Идея состоит в том, чтобы установить логическую обработку в контроллере. Установите значение true перед ajax и false после. Проблема заключается в том, что значение не возвращается в его ложное состояние. Запуск метода $ apply или $ digest возвращает Error: [$rootScope:inprog].

После Аякса я бегу

console.log($scope.processing); console.log(this.processing); console.log($scope);

Возвращение

undefind undefind И возвращает объект $ Scope. Однако в объекте $ scope, выведенном в консоли, значение обработки будет таким, каким оно должно быть (false).

Однако это не отражено в пользовательском интерфейсе, это по-прежнему актуально. Нажатие кнопки переключения устанавливает для значения обработки значение false и пользовательский интерфейс обновляется. Так что я супер запутался, где проблема ...

HTML

<div class="panel panel-default" ng-controller="UnitOfMeasureController as uom"> 
      <div class="panel-heading"> 
      <h3 class="panel-title">Create new Unit of Measure</h3> 
      </div> 
      <div class="panel-body"> 
      <div ng-hide="uom.processing"> 
      <form ng-submit="uom.processForm()" id="new_uom_form"> 
       <div class="form-group"> 
       <label for="uom_input01">Name</label> 
       <input ng-model="uom.formData['name']" type="text" class="form-control" id="uom_input01" placeholder="" name="uom[input01]" value="{{\xsds::old('uom.input01',$values)}}"> 
       </div> 
       <div style="text-align:right"><button type="submit" class="btn btn-primary" ><i class="fa fa-plus-square"></i> Create new Unit of Measure</button></div> 
       </form> 
       </div> 
       {!!\xsds::angularLoader('ng-show="uom.processing"')!!} 
      </div> 
      <button ng-click="uom.processing = false">Toggle</button> 
      <%uom.processing%> 
     </div> 

app.js

(function(){ 
var app = angular.module('ingredients',[], function($interpolateProvider) { 
$interpolateProvider.startSymbol('<%'); 
$interpolateProvider.endSymbol('%>'); 
}); 


app.controller('UnitOfMeasureController', ['$scope','$http', function($scope,$http) { 
formData = []; 
this.processing = false; 
this.processForm = function(){ 
    this.processing = true; 

    $http.get(document.js_root+'/recipe/ingredients/uom/ajax-create'). 
     success(function(data, status, headers, config) { 
     /* $scope.$apply(function(){ 
       $scope.processing = false; 
      });*/ 
      console.log($scope.processing); 
      console.log(this.processing); 
      console.log($scope); 

      $scope.processing = false; 
      if (!data.success) { 
       console.log(data.errors); 
      } else { 
       console.log('success'); 
      } 

      //$scope.$digest(); 
      //$scope.$apply(); similar but slower 
     /* $scope.$apply(function() { 
       $scope.processing = false; 
      });*/ 
     }). 
     error(function(data, status, headers, config) { 
      $scope.processing = false; 
     if(document.is_js_dev){ 
      alert(status+' '); 
     }    
     });  

    return false; 
}; 
}]); 



})(); 

ответ

0

переменная this внутри функции успеха $ http.get не может быть this вы хотите больше. Фактически this возможно somebody that you used to know, но теперь вы забыли!

Я изменил код для демонстрации

app.controller('UnitOfMeasureController', [ 
    '$scope', 
    '$http', 
    UnitOfMeasureController 
]); 

function UnitOfMeasureController($scope,$http) { 
    var vm = this; 
    vm.processing = false; 
    vm.processForm = processForm; 

    function processForm(){ 
     vm.processing = true; 

     var url = document.js_root+'/recipe/ingredients/uom/ajax-create'; 
     return $http 
      .get(url) 
      .success(function() { 
       vm.processing = false; 
      }) 
      .error(function(err) { 
       vm.processing = false; 
      });   
    }; 
} 

Но я думаю, вы должны переместить $ http.get часть к службе, как RecipeService или любое имя вы хотите.

Посмотрите на https://github.com/johnpapa/angular-styleguide для лучшей практики углового стиля. Это самое актуальное руководство, на которое ссылается даже сам Google.

+0

Хорошо, хорошо. Однако мне нужно было заменить $ scope на vm в возврате http. Почему Фак делает это иначе??! Я не вижу логики ... Это в основном означает, что «это» задание было изменено? И vm всегда будет контролироваться. – Shane

+0

Вы были верны. На самом деле я верю в успех func, 'this' ссылается на $ http сам. Все говорят о 'this' http://stackoverflow.com/questions/3127429/how-does-the-this-keyword-work –

0

Вы код контроллера должен сбросить пометка this.processing = false; вместо $scope.processing = false; как вы используете синтаксис controllerAs.

Дополнительно использовать var vm = this; затем использовать vm вместо this

контроллер

app.controller('UnitOfMeasureController', ['$scope','$http', function($scope,$http) { 
    var vm = this; 
    //then use this in your controller instead of this 
}]); 
+0

Добавление 'this.processing = false' не оказывает никакого эффекта. Если я вхожу в консоль значение this.processing до и после ее назначения, я получаю «undefined» и «false». Где он должен выводить «true», а затем «false». Тем не менее пользовательский интерфейс остается прежним. – Shane

+0

@Shane вы заменили 'this' на' vm' в своем контроллере –

+0

@Shane вы посмотрели мое обновление .. ответ, который вы принимаете, имеет то же самое, что я охватываю в мой ответ. Не могли бы вы проверить его. –

0

Да, var vm = this; бы способом.

Или вы можете использовать .bind(this) по вашим методам успеха или ошибки. С ES6 вы можете использовать arrow functions.

Пожалуйста, взгляните на это jsfiddle. Та же демонстрация, что и ниже.

var app = angular.module('ingredients', [], function ($interpolateProvider) { 
 
    $interpolateProvider.startSymbol('<%'); 
 
    $interpolateProvider.endSymbol('%>'); 
 
}); 
 

 

 
app.controller('UnitOfMeasureController', ['$scope', '$http', function ($scope, $http) { 
 
    formData = []; 
 
    this.processing = false; 
 
    this.processForm = function() { 
 
     this.processing = true; 
 
     
 
     var onSuccess = function (data, status, headers, config) { 
 
      /* $scope.$apply(function(){ 
 
       $scope.processing = false; 
 
      });*/ 
 
      //console.log($scope.processing); 
 
      console.log(this.processing); 
 
      //console.log($scope); 
 

 
      this.processing = false; 
 
      /*if (!data.success) { 
 
       console.log(data.errors); 
 
      } else {*/ 
 
      console.log('success', data); 
 
      //} 
 

 
      //$scope.$digest(); 
 
      //$scope.$apply(); similar but slower 
 
      /* $scope.$apply(function() { 
 
       $scope.processing = false; 
 
      });*/ 
 
     }; 
 
     
 
     var onError = function (data, status, headers, config) { 
 
      this.processing = false; 
 
      if (document.is_js_dev) { 
 
       alert(status + ' '); 
 
      } 
 
     }; 
 
     
 
     $http.jsonp('http://www.mocky.io/v2/5568b30150223de60c64f24f/?callback=JSON_CALLBACK').//document.js_root + '/recipe/ingredients/uom/ajax-create'). 
 
     success(onSuccess.bind(this)). 
 
     error(onError.bind(this)); 
 

 
     return false; 
 
    }; 
 
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> 
 
<div class="panel panel-default" ng-app="ingredients" ng-controller="UnitOfMeasureController as uom"> 
 
    <div class="panel-heading"> 
 
     <h3 class="panel-title">Create new Unit of Measure</h3> 
 

 
    </div> 
 
    <div class="panel-body"> 
 
     <div ng-hide="uom.processing"> 
 
      <form ng-submit="uom.processForm()" id="new_uom_form"> 
 
       <div class="form-group"> 
 
        <label for="uom_input01">Name</label> 
 
        <input ng-model="uom.formData['name']" type="text" class="form-control" id="uom_input01" placeholder="" name="uom[input01]" value="{{\xsds::old('uom.input01',$values)}}"> 
 
       </div> 
 
       <div style="text-align:right"> 
 
        <button type="submit" class="btn btn-primary"><i class="fa fa-plus-square"></i> Create new Unit of Measure</button> 
 
       </div> 
 
      </form> 
 
     </div><!--{!!\xsds::angularLoader('ng-show="uom.processing"')!!}</div>--> 
 
    <button ng-click="uom.processing = !uom.processing">Toggle</button> 
 
    <%uom.processing%> 
 
</div>

Смежные вопросы