【问题标题】:How to get the current state of a $scope variable in AngularJS in a callback function?如何在回调函数中获取 AngularJS 中 $scope 变量的当前状态?
【发布时间】:2015-03-26 19:53:40
【问题描述】:

我在使用服务/工厂作为 REST 接口并在 create 方法的回调函数中访问 $scope 变量的当前数据时遇到问题:

controllers.controller('ResourceAddCtrl', ['$scope', ... 'Resource','ResourceComb',
        function($scope, ...) {
            ...
            $scope.selectedEntryId = {};
            $scope.resource = new Resource();
            $scope.addResource = function(){
                $scope.resource.$create(function(response){
                    var id = response.id;
                    console.log($scope.selectedEntryId);
                    //ResourceComb.$create({res_id : id, rescomb_id : $scope.selectedEntryId},function(){});

                }); 
            };
        }]);

问题是 $scope.selectedEntryId 在回调方法中始终是它的初始值,尽管它在 html 代码中与 ng-model 一起使用,并且值得到完美更新,因为 {{selectedEntryId}} 在键入 a 时会产生预期的输出bindet 输入字段中的数字。 任何人都知道我的错误在哪里,或者我如何解决这个问题?

【问题讨论】:

  • 您可以在绑定到selectedEntryId 的位置发布您的HTML/模板吗?将selectedEntryId 设置在$scope 的子范围内的ng-model 是否?
  • 您创建了一个新资源,但从未向它提供任何数据。检查发送的请求。剩下的问题需要看html
  • 相关 HTML-src 如下您可以在 Angular 文档中找到回调。

标签: javascript angularjs rest angularjs-scope angularjs-service


【解决方案1】:

这可能太明显而无法解决您的问题,但在我看来,您需要在返回值后设置范围内的值。

// fwiw I'd prob. make the default a string
$scope.selectedEntryId = '';
$scope.resource = new Resource();
$scope.addResource = function(){
  $scope.resource.$create(function(response){
    // Set the ID on the scope
    $scope.selectedEntryId = response.id;
    // This is trivial now, but it will be the correct value
    console.log($scope.selectedEntryId);
    // ...and the HTML should automatically update itself, as well.
  }); 
};

【讨论】:

  • 在我看来,资源需要范围数据才能将任何内容发送到服务器……我错过了什么吗?
  • 有可能,但这取决于create 操作的作用。如果它只是创建一个空白资源,那么它不需要任何数据。它将接受 undefined,创建空白资源,并返回 ID。
  • 我猜,我自己从来没有创建过空白,用空白填充数据库似乎很奇怪
  • 哈。我不同意你的看法。这似乎太明显了,无法成为答案,但是,嘿,也许是:)
  • 好吧,问题不在于创建成功时如何从服务器获取返回的数据。确实,服务器在Response 中返回了一个“id”,我稍后需要使用它。但是获得这个 id 没有问题,所以我减少了代码。问题是我需要稍后在此回调中比较返回的 id 和 selectedEntryId,这将由用户在视图上更改。
【解决方案2】:

我假设Resource 是一个ngResource,在这种情况下,您传递给$create 的函数不是回调。

来自文档:

  • HTTP GET“类”操作:Resource.action([parameters], [success], [error])
  • 非 GET “类”操作:Resource.action([parameters], postData, [success], [error])
  • 非 GET 实例操作:instance.$action([parameters], [success], [error])

AngularJS $resource Docs

因此,在您的代码中,您实际上传递的是 [parameters],而不是 [success] - 因此在函数运行时尚未进行调用,因此 selectedEntryId 是其初始值。

鉴于此,请尝试以下操作:

$scope.addResource = function(){
     $scope.resource.$create(null, function(response){
        var id = response.id;
        console.log($scope.selectedEntryId);
        //ResourceComb.$create({res_id : id, rescomb_id : $scope.selectedEntryId},function(){});

     }); 
};

【讨论】:

  • 是的,您的假设是正确的。资源定义如下:services.factory('Resource', ['$resource', function($resource){ return $resource('resources/:id', {id:'@id'}, { query: { method:'GET', url:'resources', isArray:false}, update: { method: 'PUT', transformRequest: function(data, headersGetter){ delete data['id']; return angular.toJson(data); } }, create: {method: 'POST'}, delete: {method: 'DELETE'} }); }]);
  • 但是您的解决方案也不起作用。当单击调用addResource() 方法的按钮时查看控制台,成功回调被执行,因为将console.log($scope.selectedEntryId); 行更改为console.log('id:' + angular.toJson($scope.selectedEntryId)); 表示它已执行但 selectedEntryId 的值仍然是其初始值。
【解决方案3】:

好吧,真正的问题是不同的。我尝试了一个新的简单示例(Plunker ) 并发现原因一定是 ngInclude。我没想到这会产生影响:看这个例子: 在主控制器中更改模型总是在一个方向上更新,但在包含页面中的另一种方式更改控制器变量 x 不会更新。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多