【问题标题】:How to update scope variable value in view after http call?http调用后如何更新视图中的范围变量值?
【发布时间】:2017-03-14 23:37:50
【问题描述】:

我正在使用 Angularjs 1.4.3 制作我的第一个项目。

在我的控制器中,我正在发出 http 请求,在此 http 请求的 success 方法中,我正在更新范围变量。在 http 调用中,我得到了最新的值,但在视图方面它没有更新值。

Plunker Link(谢谢@rupesh_padhye)。 (由于调用的是servlet action,所以Plunker中不会显示任何数据)

app.controller('measuresCtrl', ['$scope', '$modal', '$http', function($scope, $modal, $http) {



    $scope.groups = []
        $scope.loadAllMeasure = function() {
            $http.get("fetchAllMeasure")
            .success(function(data) {
                console.log("Before insert");
                console.log($scope.groups);

                $scope.groups = data.measures;

                console.log("After insert");
                console.log($scope.groups);
            })
            .error(function() {
            });
        };

        $scope.loadAllMeasure();

$scope.submit = function (form) {
$http({
        method: 'POST',
        url: 'saveMeasure',
        data: {
               id: form.id,
               name: form.name,
               description: form.description
              },
        headers: {'Content-Type': 'application/x-www-form-urlencoded'}
        }).success(function(data, status, headers, config) {
           $scope.loadAllMeasure();
        }).error(function(data, status, headers, config) {
   });
 }

})

每当我对度量执行任何 CRUD 操作时,我都会调用方法 $scope.loadAllMeasure();。但它不会更新视图(jsp)页面中的值。

我已经尝试过 $scope.$apply 方法,但我得到了Error: $digest already in progress

当我在 success 方法中使用 console.log 打印 $scope.groups 的值时,它会显示最新的值。

在我的视图 (jsp) 页面中,我只是使用 ng-repeat 函数以表格格式显示所有记录。

我的视图页面的代码(最少的代码)-

<div ng-repeat="group in groups | orderBy:'name'">
    <div>
        <input type="checkbox" id="checkbox-{{group.id}}" class="ui-checkbox" /><label for="checkbox-{{group.id}}">{{group.name}}</label>
    </div>
    <div>{{ group.description}}</div>
    <div>   
            <div class="fa fa-pencil button" data="{{group.id}}" id="{{::elementId}}" ng-click="showEditForm(group.id, $event)"></div>
            <div class="fa fa-trash button" data="{{group.id}}" ng-click="deleteGroup(group.id)"></div>
            <div class="fa fa-clone button" data="{{group.id}}" id="{{::elementId}}" ng-click="showCloneForm(group.id, $event)"></div>
    </div>
</div>

console.log 中的值为

Before insert
Object { id=1,  description="Measure Description1",  name="Demo"}]

After Insert
 [Object { id=1,  description="Measure Description1",  name="Demo"}, Object { id=2,  description="Description2",  name="Demo2"}]

http调用后如何更新视图中的作用域变量值?

【问题讨论】:

  • 你不需要更新作用域变量,$http 会自动更新
  • 那为什么它会显示旧值?
  • 你可以发布视图吗?
  • 你需要使用 ng-model="id",而不是 data="{{group.id}}"
  • data="{{group.id}}" 没有问题,我没有向用户显示 id

标签: javascript angularjs jsp http angularjs-scope


【解决方案1】:

将新数据分配给 $scope 变量调用后:

$scope.$digest();

这将更新当前范围值

此处参考:https://docs.angularjs.org/api/ng/type/$rootScope.Scope

【讨论】:

  • 谢谢,它对我有用。我正在将 $scope 变量更新为事件处理函数(socket.io 的 .on()),但是当第二次调用该函数时,视图中的变量值发生了变化。
【解决方案2】:

我看不出你的示例代码有什么问题。

我创建了一个 JSFiddle 来尝试帮助你。

服务器调用已替换为返回承诺的 setTimeout 函数。

请看 JSFiddle https://jsfiddle.net/sjwkbzxa/

请看下面的例子:

<div data-ng-controller="TestController as vm">
    <button data-ng-click="loadAllMeasure()">Load List from Server</button>
    <ul>
        <li data-ng-repeat="group in groups | orderBy:'name'">
            <span>{{group.description}}</span>
        </li>
    </ul>
</div>

javascript:

angular.module('application',[]).controller("TestController", ['$scope', '$q', function($scope, $q){    
    $scope.groups = [{ id:1,  description:"Initial List",  name:"Demo"}];

    $scope.loadAllMeasure = function(){
       loadData().then(function(data){
         $scope.groups = data;
       });
     };

    function loadData(){
        var deferred = $q.defer();
        setTimeout(function(){
            var data = [{ id:1,  description:"Measure Description1",  name:"Demo"}, { id:2,  description:"Description2",  name:"Demo2"}];
            deferred.resolve(data);
        }, 3000);
       return deferred.promise;
    }
}]);

也许您遗漏了一些我们看不到的东西?

【讨论】:

  • 谢谢,实际上我无法在小提琴中演示它,因为我的数据是通过 servlet 响应来自数据库的。使用您提到的静态数据可以正常工作,但使用动态数据则无法正常工作。我可以在数据库 console.log 中看到更新的值,但在 View 中看不到 :(
  • @Deepu 如果它不适用于来自服务器的数据,则意味着您从服务器获取的数据格式不正确。如果您使用setTimeout 或使用来自 API 的数据也没有什么不同。
  • 数据格式正确,如果我刷新页面,我将获得所有更新的数据。因为当控制器加载时我正在调用$scope.loadAllMeasure 方法,但即使在保存措施之后我调用了相同的方法,它也不会更新列表。但是当我刷新页面时,它会显示所有数据。
  • 能否添加您在“因为加载控制器时我正在调用$scope.loadAllMeasure 方法”中提到的代码
  • 是的,在声明 $scope.loadAllMeasure 后立即更新,有问题。
【解决方案3】:

我回答这个问题有点晚了,但这是我的 2 美分:

将服务器数据 (response.data) 简单地分配给 $scope 对象似乎对我不起作用

$scope.something = response.data //didn't work

所以,我从服务返回了一个承诺对象到控制器中,然后使用

angular.copy(response.data,$scope.something) 

复制从服务器返回的值。您还可以将 $scope.something 作为函数的参数传递给服务,并在服务函数中使用 angular.copy,但我不知道这样做是否是一个好习惯。

【讨论】:

  • $http 是异步调用,如果响应延迟,则 angular.copy 中的值将与响应值不同。无论如何感谢您的回复。
  • 抱歉不清楚...我在 $http 调用返回的承诺的“then”子句中使用了 angular.copy(source,dest)。到目前为止,谢天谢地,我还没有看到您报告的问题,但会密切关注。感谢您的提醒。
【解决方案4】:
 $scope.loadAllMeasure = function() {
     CalltoServer();
 };

 CalltoServer = function() {
    return $http.get("fetchAllMeasure")
    .success(function(data) {
        $scope.groups = data.measures;
    })
    .error(function() {
    });
 }

试试这个,2 到 3 秒后会成功,所以我猜在事件中它需要 rist 来绑定

【讨论】:

  • 这个也没有运气:(
  • ng-controller="measuresCtrl" 添加 ?或在路由中声明的控制器?如果不是,它不适用于某些情况,我没有发现您的代码有任何错误
  • 我的控制器是 measuresCtrlfetchAllMeasure 是来自 servlet 的操作方法。
  • 添加额外的方法有什么区别?
  • .success(function(data) { //这里会在成功之后 }) $http 请求在另一个角度事件中,导致绑定困难
【解决方案5】:

嘿,我也遇到了同样的问题,如果有人还在寻找,那是由 $http 中的 $scope 变量的变化引起的。我认为在成功函数中创建了一个新的 $scope(一些原型继承的东西)。 所以复制变量 $scope,类似于

var s = $scope;

然后改变

s.groups = someData;

您的代码:

app.controller('measuresCtrl', ['$scope', '$modal', '$http', function($scope, $modal, $http) {


var s = $scope;
$scope.groups = []
    $scope.loadAllMeasure = function() {
        $http.get("fetchAllMeasure")
        .success(function(data) {
            console.log("Before insert");
            console.log($scope.groups);

            s.groups = data.measures;

            console.log("After insert");
            console.log($scope.groups);
        })
        .error(function() {
        });
    };

    $scope.loadAllMeasure();

$scope.submit = function (form) {
$http({
    method: 'POST',
    url: 'saveMeasure',
    data: {
           id: form.id,
           name: form.name,
           description: form.description
          },
    headers: {'Content-Type': 'application/x-www-form-urlencoded'}
    }).success(function(data, status, headers, config) {
       $scope.loadAllMeasure();
    }).error(function(data, status, headers, config) {
});
}
})

【讨论】:

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