【问题标题】:Angular controller scope not updating after jQuery ajax calljQuery ajax 调用后 Angular 控制器范围未更新
【发布时间】:2014-01-15 01:51:07
【问题描述】:

我有这段代码,但我看不出问题的根源在哪里,我在 chrome 控制台中没有收到任何错误 我的控制器:

function notifController($scope) {
  $scope.refreshMsgs = function () {
    $.post("notification-center-trait.aspx")
      .success(function (data) {
        $("#loadedthings").html(data);
        newMsgs = JSON.parse($("#label1").html());
        $scope.msgs = newMsgs;
      });
  }
  $scope.refreshMsgs();
}

label1label2 在 div 中被正确加载;

控制台中的newMsgs 会按照应有的方式进行解析;

我让它在其他页面上工作,但似乎我错过了这个页面上的一些东西。我有 <html ng-app> 标签:

<div ng-controller="notifController"> 
    <div class="row">
    {{msgs.length}} new msgs : 
              <table class="table">
                  <tbody >
                      <tr ng-repeat="msg in msgs">
                        <td>
                            {{msg.sender}}
                        </td>
                        <td>
                            {{msg.message}}
                        </td>
                        <td>
                            {{msg.date}}
                        </td>
                      </tr>
                  </tbody>
              </table>
</div>
</div>

当我执行此操作时,我在控制台中得到“未定义”:angular.element($0).scope()

【问题讨论】:

  • 你确定$0 工作正常吗?我不知道你在做什么......
  • 我测试了你的代码,这里一切正常。我怀疑你不恰当地弄乱了 DOM 并且犯了一个错误。像angular.element 这样的任何东西都属于指令。 Angular 使 scope 属性在你需要的任何地方都可用,除了可能罕见的例外,所以你不应该需要以这种方式访问​​元素或范围。
  • @m59 我刚刚在 chrome 控制台中执行了angular.element($0).scope(),只是为了看看我的范围内发生了什么link,但我得到'未定义'
  • 正如我所说,使用您这里的代码,控制器已初始化并且数据绑定正在工作。此代码未传达您遇到的问题。为了绝对确定,请执行以下操作:$scope.foo = 'test' 并在您的标记中:{{foo}}。也许您的 ajax 调用没有通过?如果控制器真的不工作,其他的东西(不在此代码中)是问题。
  • 你刚才描述的甚至是无效的......那必须是{{foo}}。你肯定有一个简单的错误,你可以用控制台调试,我敢肯定。此外,Angular 有 $http 用于 ajax 调用,你应该使用它而不是 jQuery。

标签: javascript angularjs angularjs-scope


【解决方案1】:

忽略我在 cmets 中指出的其他架构问题,真正的问题是您使用的是 jQueryajax 而不是 Angular 的 $http。当你不通过 Angular 做这样的事情时,你是在 Angular 的范围之外工作,它不知道变化。虽然不理想,但您可以使用 $scope.$apply 让 Angular 知道某些内容在其知识范围之外进行了更新。看起来像这样:

$scope.$apply(function() {
  $scope.msgs = newMsgs;
});

这告诉 Angular 你已经从它不知道的上下文中修改了它需要知道的东西(在这种情况下是 jQuery ajax 调用)。

$scope.$apply() 有一些有效用途,例如在事件处理程序中,但大多数其他时候它是不良做法的标志。您绝对应该使用 Angular 的 $http 进行 ajax 调用。

【讨论】:

  • 作为附录,如果你在错误的时间使用它,$scope.$apply 可能会抛出错误(你不能把它放在任何你行为不端的地方,作为所有问题的解决方案),但是,$timeout(setTimeout 的 Angular 包装器)将一直运行,并确保您的更改最终在 next $apply pass 中结束(无论如何它们都会到达那里)。它不应该被滥用,但它比 $apply 更安全,在指令中没有肮脏的 hack,检查它是否安全/需要。
  • @Norguard True...但是如果您曾经在引发错误的地方使用$apply,则根本不应该使用它。这是一个巨大的代码气味。就像我说的,$apply 通常根本不需要,除非您使用事件或第三方库。
  • 绝对。但是其中一些第三方库是半同步、半异步的,而另一些则进入了他们自己的 pub/sub 或 setTimeout 的兔子洞,或者只是要求您自己在这些圈子中围绕它们跳舞。我第一手知道,如果您不小心,MasonryJS(用于 pinterest/infinite-tumble 布局)和 D3JS(用于制作可补间的 SVG 图)都可以通过if (!$scope.$rootScope.$$phase) 废话来提供它们的痛苦份额,如果 Angular 只是部分与流程相关(例如在 ng-repeat 上调用 Msnry.stamp + Msnry.layout ...)。 $timeout 这样就很优雅了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-02-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多