【问题标题】:AngularJS $rootScope loses value unless I use promise (trigger.io AJAX request)除非我使用承诺(trigger.io AJAX 请求),否则 AngularJS $rootScope 会失去价值
【发布时间】:2014-07-12 00:03:12
【问题描述】:

所以这很奇怪。 $rootScope 在函数中正确设置,但随后失去其价值。如果我使用承诺,我只能保持价值。 (!?)

我正在使用 trigger.io (Forge) AJAX 请求,成功后我更新$rootScope.queries。在成功块内,$rootScope.queries 设置正确,如alert 所示。

.run(function($rootScope, $state, $q) {
    var retrieveHistory = function() {
        forge.logging.log("Retrieving history");
        // Retrieve the history
        forge.request.ajax({
          type: 'GET',
          url: 'http://localhost:9000/json',
          dataType: 'json',
          success: function (data) {
            $rootScope.queries = data["queries"];
            alert("queries " + JSON.stringify($rootScope.queries));
          },
          error: function (error) {
          }
        });
    }
    retrieveHistory();

此时,在调用 retrieveHistory() 之后,$rootScope.queries 现在为空。视图没有更新,使用 Chrome 控制台检查显示它是空的。

假设我向函数添加了一个承诺,但实际上并没有将承诺用于任何事情。

.run(function($rootScope, $state, $q) {
    var retrieveHistory = function() {
        var deferred = $q.defer();
        forge.logging.log("Retrieving history");
        // Retrieve the history
        forge.request.ajax({
          type: 'GET',
          url: 'http://localhost:9000/json',
          dataType: 'json',
          success: function (data) {
            $rootScope.queries = data["queries"];
            alert("queries " + JSON.stringify($rootScope.queries));
          },
          error: function (error) {
            deferred.reject("error " + JSON.stringify(error));
          }
        });

        return deferred.promise;
    }
    var promise = retrieveHistory();
    promise.then();

有了这个承诺,$rootScope.queries 将保持其价值。视图更新,Chrome 检查器显示该值设置正确。

这是为什么?我根本不理解这种行为。为什么我不能在原始代码中保留$rootScope.queries 的值?为什么 promise 会保值?

【问题讨论】:

    标签: angularjs angularjs-scope promise trigger.io angular-promise


    【解决方案1】:

    好的,2 个问题。

    1. 为什么要使用 trigger.ajax 而不是 $http pr 资源,这些资源是 Angular 本机服务,因此完全了解 angulars diges 循环而不是外部库的情况。
    2. 您为什么要使用 rootscope,除非您在服务内广播事件,否则您真的不应该这样做。我知道没有充分的理由污染您的 rootscope。

    你的问题很可能是因为 forge.ajax 在角度摘要之外,所以你需要执行。

    $rootScope.$apply() 
    

    让 rootscope 知道他需要注意一些变化

    【讨论】:

    • 正确 (plnkr.co/edit/plrufZXBFYtC5vMZcJ4a?p=preview),并且该承诺有效,因为它为您运行了一个摘要循环。
    • 1) 我使用 forge.request 是因为“通常,页内 JavaScript 只能向托管当前网页的服务器发出 XMLHttpRequest (XHR)。” (trigger.io/modules/request/current/docs/index.html) 我可以使用 $http 吗?
    • 2) 我正在使用 rootScope,因为我是 Angular 的新手,而且我不知道如何访问另一个控制器的范围。我知道这很糟糕,我会尽快更改。
    • 我在 $rootScope 更新成功后添加了$rootScope.$apply()。这在 web 中有效,但在 trigger.io 上的 ios 中无效。如果我在 $rootScope.$apply() 之后立即记录一条消息,我会在 web 上看到该消息,但看不到 ios。为什么?
    • 我尝试使用 $http 但我收到以下错误:XMLHttpRequest cannot load localhost:9000/json。请求的资源上不存在“Access-Control-Allow-Origin”标头。
    猜你喜欢
    • 2017-12-22
    • 1970-01-01
    • 2017-04-01
    • 2015-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-31
    • 2013-07-30
    相关资源
    最近更新 更多