【问题标题】:AngularJS Why is this controller variable not getting updated in the UI?AngularJS 为什么这个控制器变量没有在 UI 中更新?
【发布时间】:2020-05-17 15:53:15
【问题描述】:

我有一个控制器,它使用 StompJS 订阅一个 url(后端是 Spring Java),它每 5 秒返回一个交替的字符串“list”和“box”。我想在 StompJS 收到一些数据时更新我的​​ UI 元素,但我无法更新 UI 元素。我已经用$timeout 测试了相同的逻辑,并且 UI 正在更新,因此它必须与回调函数的工作方式有关。谁能看到 UI 没有更新的原因是什么?

我有这些简单的 UI 元素:

<input ng-model="ctrl.uniqueId"/>
<input ng-model="test"/>

ctrl.uniqueId是验证实际控制器实例是否正在更新。出于某种原因,每次只有 1 个控制器进行 5 次不同的订阅。如果有人可以提供帮助,那就太好了,但我怀疑除非你看到我所有的代码设置,否则你能得到很多信息。

无论如何,在我的控制器中(尝试了 self.test 并没有用,所以我尝试使用 $scope.test 看看它是否有所作为):

self.uniqueId = window.performance.now();
$scope.test = 'list';

// the UI will be updated to dummy after 3 seconds.
$timeout(function() {
    $scope.test="dummy";
}, 3000);

// the UI will not update.
var callBackFn = function(progress) {
    $scope.test = progress;
    console.log(self.uniqueId + ": " + $scope.test);
};

// the server returns alternating data (list and box) every 5 seconds
MyService.subscribeForUpdate('/topic/progressResults', callBackFn);

如果重要的话,这是我的 StompJS 服务代码:

self.subscribeForUpdate = function(channelUrl, callBackFn) {
    self.socket.stomp.connect({}, function() {
        self.socket.subscription = self.socket.stomp.subscribe(channelUrl, 
            function (result) {
                //return angular.fromJson(result.body);
                callBackFn(result.body);
                return result.body;
            }
        );
    });
};

这是console.log 结果:

1831.255000026431: list
1831.255000026431: box

补充:没有类似Promise的回调函数是否可以获取返回数据?

【问题讨论】:

    标签: angularjs callback angularjs-scope model-binding stompjs


    【解决方案1】:

    请务必使用$apply:

    app.service("myService", function($rootScope) {
        var self = this;
        self.subscribeForUpdate = function(channelUrl, callBackFn) {
            self.socket.stomp.connect({}, function() {
                self.socket.subscription = self.socket.stomp.subscribe(channelUrl, 
                    function (result) {
                        //return angular.fromJson(result.body);
                        $rootScope.$apply(function() {
                            callBackFn(result.body);
                        });
                        return result.body;
                    }
                );
            });
        };
    })
    

    AngularJS 通过提供自己的事件处理循环来修改正常的 JavaScript 流程。这将 JavaScript 拆分为经典和 AngularJS 执行上下文。只有在 AngularJS 执行上下文中应用的操作才能受益于 AngularJS 数据绑定、异常处理、属性监视等……您也可以使用 $apply() 从 JavaScript 进入 AngularJS 执行上下文。

    请记住,在大多数地方(控制器、服务),处理事件的指令已经为您调用了 $apply。只有在实现自定义事件回调或使用第三方库回调时,才需要显式调用 $apply。

    有关详细信息,请参阅

    【讨论】:

      【解决方案2】:

      这是一个非常常见的问题,当 3rd 方库(在 angular 环境之外)与 angularjs 一起使用时会发生。在这种情况下,您需要使用以下命令手动触发摘要循环:

      $scope.$apply()

      之后,所有角度绑定都将更新。使用 $timeout(即使没有 timeValue)也有同样的结果,因为它也会触发$apply()

      【讨论】:

      • 谢谢。两个答案都是正确的,并且基于您首先发布的时间戳。由于示例更详细,我选择了另一个答案为正确的。我衷心感谢您的帮助。
      • 没事没问题!
      猜你喜欢
      • 2023-04-08
      • 1970-01-01
      • 2015-10-19
      • 2022-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-22
      相关资源
      最近更新 更多