简体   繁体   English

AngularJS - UI不能很好地更新

[英]AngularJS - UI Does Not Update Well

I have an AngularJS app. 我有一个AngularJS应用程序。 My controller looks like this: 我的控制器看起来像这样:

myApp.controller('MyCtrl', ['$scope', '$http', function ($scope, $http) {
  $scope.items = [];

  // ProfileUpdate: 0=Not Checked, 1=Checked, 2=Failed, 3=Succeeded
  $scope.items.push({
    name: 'Chicago Fire', players: [
      { number: 1, profileUpdated:0, name: 'Bill' },
      { number: 2, profileUpdated:0, name: 'John' }
    ]
  });

  $scope.items.push({
    name: 'Philadelphia Ice', players: [
      { number: 3, profileUpdated:0, name: 'Phil' },
      { number: 4, profileUpdated:0, name: 'Flo' }
    ]
  });

  ...

  $scope.currentTeamIndex = 0;
  $scope.currentPlayerIndex = 0;
  $scope.execute = function() {
        $http.get(playerRelatedUrl)
          .then(
            function(res) {
              $scope.items[$scope.currentTeamIndex].players[$scope.currentPlayerIndex].profileUpdated = 3;
            },
            function(err) {
$scope.items[$scope.currentTeamIndex].players[$scope.currentPlayerIndex].profileUpdated = 2;
            }
          )
  }
}]);

My intent is to iterate through each team and attempt to update the players profile. 我的目的是遍历每个团队并尝试更新玩家资料。 I want to reflect what is happening in the UI. 我想反映UI中发生的事情。 In an effort to do this, I have the following in my view: 为了做到这一点,我在观点中有以下内容:

<button ng-click="execute()">Execute</button>
<div ng-repeat="team in items">
  <h2>{{team.name}}</h2>
  <div ng-repeat="player in team.players">
    <ul class="list-inline">
      <li>
        <div ng-switch="player.profileUpdated">
          <h3 ng-switch-when="0">Not checked yet</h3>
          <h3 ng-switch-when="1">Checking...</h3>
          <h3 ng-switch-when="2">Unable to update</h3>
          <h3 ng-switch-when="3">Updated!</h3>
        </div>
      </li>
      <li>{{player.name}}</li>
    </ul>
  </div>
</div>

This code renders correctly initially. 此代码最初正确呈现。 However, when the execute button gets clicked, both "Checking..." and "Updated" appear. 但是,单击执行按钮时,将显示“正在检查...”和“已更新”。 After a second or two, the word "Checking..." goes away. 一两秒后,“检查......”这个词就消失了。 After some investigation, I learned my web service call is executing in ~90 ms. 经过一番调查,我了解到我的Web服务调用正在~90毫秒内执行。 That would explain why the word "Updated" seems to appear so quickly. 这可以解释为什么“更新”这个词看起来似乎很快。 However, it does not explain why it takes so long for the word "Checking..." to go away. 但是,它并没有解释为什么“检查......”这个词需要很长时间才能消失。

Can someone please explain to me what I'm doing wrong? 有人可以向我解释我做错了什么吗?

Thanks! 谢谢!

Sometimes you have to work around the limitations of the framework. 有时你必须解决框架的局限性。 In this case, there is actually a potentially simpler solution. 在这种情况下,实际上有一个更简单的解决方案。

In the JavaScript, why not set the status as a string instead of an integer? 在JavaScript中,为什么不将状态设置为字符串而不是整数?

$scope.execute = function() {
    $http.get(playerRelatedUrl)
      .then(
        function(res) {
                                                              // NOTICE THE STATUS IS A STRING HERE vvvvvvvvv
            $scope.items[$scope.currentTeamIndex].players[$scope.currentPlayerIndex].profileStatus= "Updated";
        },
        function(err) {
            $scope.items[$scope.currentTeamIndex].players[$scope.currentPlayerIndex].profileStatus = "Unable to update";
        }
      )
}

Then eliminate the switch from the HTML entirely. 然后完全取消HTML中的切换。 The code becomes much easier to read. 代码变得更容易阅读。

<button ng-click="execute()">Execute</button>
<div ng-repeat="team in items">
  <h2>{{team.name}}</h2>
  <div ng-repeat="player in team.players">
    <ul class="list-inline">
      <li>
        <div>
          <h3>{{player.profileStatus}}</h3>
        </div>
      </li>
      <li>{{player.name}}</li>
    </ul>
  </div>
</div>

If you really, really need to have an integer state variable for some reason, then write a little function and just do both: 如果你真的,由于某种原因确实需要一个整数状态变量,那么写一个小函数,然后做两个:

function updatePlayerStatus( newValue ) {
    var statusUpdateStrings = [ "Not checking", "Checking", ... etc. ];
    var player = $scope.items[$scope.currentTeamIndex].players[$scope.currentPlayerIndex];
    player.profileUpdated = newValue;
    player.profileStatus= statusUpdateStrings[ player.profileUpdated ];
}

$scope.execute = function() {
    $http.get(playerRelatedUrl)
      .then(
        function(res) {
            updatePlayerStatus(3);
        },
        function(err) {
            updatePlayerStatus(2);
        }
      )
}

AngularJS $http service returns a "promise", which means it returns a sort of placeholder for the return value immediately, but that placeholder will eventually be populated with the actual return value. AngularJS $ http服务返回一个“promise”,这意味着它会立即为返回值返回一种占位符,但该占位符最终将填充实际的返回值。 That is, when the web service responds. 也就是说,当Web服务响应时。 Even if your web service call executes in 90 ms, that doesn't necessarily mean the promise has received its true value yet. 即使您的Web服务调用在90毫秒内执行,这也不一定意味着承诺已经收到其真正的价值。 It depends a bit on how you measured, I guess, but this might be the mechanism behind the "delay" you're experiencing. 我猜,这取决于你的测量方式,但这可能是你所经历的“延迟”背后的机制。 See https://docs.angularjs.org/api/ng/service/$http for reference. 请参阅https://docs.angularjs.org/api/ng/service/$http以供参考。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM