【问题标题】:Angular updating $scope variable after ajax is not reflecting in UIajax 后的角度更新 $scope 变量未反映在 UI 中
【发布时间】:2015-05-29 18:23:50
【问题描述】:

我似乎无法在这里找出问题所在。 在 ajax 成功响应中,我在当前控制器中设置了一个未反映在 UI 中的值。我发现的一般答案是使用 Angular ajax 函数和/或将 $apply 或 $digest 应用于 $scope。这些都不起作用。

请注意,在代码中,{{ 和 }} 角度标签被替换为 ,因为我正在使用刀片诱惑引擎并且这些标签冲突。

这个想法是在控制器中设置一个处理布尔值。在ajax之前设置为true,之后设置为false。问题是值没有返回到它的假状态。运行 $apply 或 $digest 方法都返回 Error: [$rootScope:inprog]

在我运行 ajax 之后

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

返回

undefind undefind 并返回 $scope 对象。 但是在控制台输出的 $scope 对象中,处理的值应该是(false)。

但它没有反映在 UI 中,但它仍然是正确的。单击切换按钮将处理值设置为 false 并更新 UI。 所以我对问题出在哪里感到非常困惑......

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



})();

【问题讨论】:

    标签: javascript ajax angularjs scope angular-http


    【解决方案1】:

    $http.get 的成功函数中的变量this 可能不再是你想要的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 自己都参考的最新指南。

    【讨论】:

    • 好吧,它工作。但是我需要在 http 返回中用 vm 替换 $scope。为什么 Fak 会有所不同!?!我看不到逻辑......它基本上意味着“这个”分配已经改变了吗?并且 vm 永远是被控制的。
    • 你是对的。事实上,我相信在成功函数内部,this 指的是 $http 本身。大家都在谈论this stackoverflow.com/questions/3127429/…
    【解决方案2】:

    你的控制器代码应该重置标志 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
    }]);
    

    【讨论】:

    • 添加 'this.processing = false` 没有任何效果。如果我在分配之前和之后登录控制台“this.processing”的值,我会得到“未定义”和“假”。它应该在哪里输出“真”,然后是“假”。用户界面仍然保持不变..
    • @Shane 你在控制器中用vm 替换了this
    • @Shane 你看我的更新了吗..你接受的答案和我在我的答案中提到的一样..你能检查一下吗..
    【解决方案3】:

    是的,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>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-02-17
      • 1970-01-01
      • 1970-01-01
      • 2016-03-12
      • 1970-01-01
      • 1970-01-01
      • 2015-04-30
      • 2021-01-06
      相关资源
      最近更新 更多