2014-11-13 2 views
3

AngularJS 앱이 있습니다. 내 컨트롤러는 다음과 같습니다 :AngularJS - UI가 제대로 업데이트되지 않습니다.

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; 
      } 
     ) 
    } 
}]); 

내 팀은 각 팀을 반복하여 선수 프로필을 업데이트하려고합니다. UI에서 무슨 일이 일어나고 있는지 반영하고 싶습니다. 이 작업을 수행하기위한 노력의 일환으로, 나는 내보기에 다음과 같은 한 :이 코드는 제대로 초기 렌더링

<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> 

. 그러나 실행 버튼이 클릭되면 "확인 중 ..."및 "업데이트 됨"이 나타납니다. 두 번째 또는 두 번째 후에 "Checking ..."이라는 단어가 사라집니다. 몇 가지 조사를 한 후 웹 서비스 호출이 ~ 90 ms에서 실행되고 있다는 것을 알게되었습니다. 그러면 "업데이트 됨"이라는 단어가 왜 그렇게 빨리 나타나는지 설명 할 수 있습니다. 그러나 "Checking ..."이라는 단어가 왜 그렇게 오래 걸리는 이유는 설명하지 않습니다.

누군가 내가 잘못하고있는 것을 설명해 줄 수 있습니까?

감사합니다.

+1

당신이 설정하는 코드를 보여 주시겠습니까 '업데이트의 프로필 = 1 '? 그 논리와 관련 될 수있는 가능성이 있습니다. (미안 내가 그것을 현재의 지위에서 놓쳤다면). 건배, [bro] (http://stackoverflow.com/users/1185425/jquery-mobile). –

+0

악마가 여기에 자세히 나와있을 수 있습니다. 우리는 어떤 유형의 데이터를 다루고 있습니까? 100 팀, 1000 팀? 팀당 얼마나 많은 선수. 팀 당 20 명의 선수를 가진 100 개 이상의 팀이있는 ng-repeat는 문자 그대로 시간의 수천을 소화 할 것입니다. ngRepeat는 성능에있어 막대한 병목 현상으로 알려져 있습니다. 당신의 스코프에 watch 명령문이 있다면, ng-repeat가 스코프 다이제스트를 일으킬 가능성이있는 동일한 양의 시간과 잠재적으로 데이터에 바인딩되고 언 바운드됩니다. – Mutmatt

+0

call $ scope. $ apply(); player.profileUpdated를 설정 한 후 – nacholibre

답변

0

AngularJS $ http 서비스는 "promise"를 반환합니다. 즉, 반환 값에 대한 일종의 자리 표시자를 즉시 ​​반환하지만 그 자리 표시자는 결국 실제 반환 값으로 채워집니다. 즉, 웹 서비스가 응답 할 때입니다. 웹 서비스 호출이 90ms 내에 실행된다고하더라도 반드시 약속이 실제 값을 수신했다는 것을 의미하지는 않습니다. 측정 방법에 따라 약간 달라 지겠지만,이 일 수 있습니다. 참고로 https://docs.angularjs.org/api/ng/service/$http을 참조하십시오.

+0

의'ng-switch'가 업데이트됩니다 ('then'에서 발생하므로 약속이 해결 된 것으로 가정합니다). 나는 실제로 같은 문제 (ng-if, ng-switch는 사용하지 않음)를 가지고 있습니다 - 겉으로보기에는 경쟁 조건이 몇 초 동안 함께 표시됩니다. – Madd0g

2

가끔 프레임 워크의 한계를 극복해야합니다. 이 경우 잠재적으로 더 단순한 솔루션이 있습니다.

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"; 
     } 
    ) 
} 

그런 다음 HTML에서 스위치를 완전히 제거하십시오. 코드를 읽기가 훨씬 쉬워집니다.

<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> 

당신이 정말로, 정말로 어떤 이유로 정수 상태 변수를 가질 필요가 있다면, 약간의 함수를 작성하고 두 단지 수행

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); 
     } 
    ) 
} 
+0

정수를 사용하는 것이 왜 적절하지 않다고 말할 수 있습니까? 이 경우 프레임 워크의 한계는 무엇입니까? –

+0

간단한 데모 (정수 및 약속 사용)를 시도하고 정상적으로 작동하는 것 같습니다. http://jsfiddle.net/26hw7evn/1/ –

+0

@I_Debug 나는 하나가 적절하거나 적절하지 않다고 말하려고하지 않습니다.때때로 우리 프로그래머는 필요한 것보다 더 복잡한 것을 만듭니다. 우리 모두 그렇게 해. 물론 스택 오버 플로우 게시에서는 모든 OP의 실제 제약 조건을 아는 것이 어렵 기 때문에 정수 상태 값에 대한 큰 이유가있을 수 있습니다. 아니면 하나도 없을 수도 있습니다. 내가 언급 한 제한 사항은 스위치가 OP가 예상 한대로 업데이트되지 않았다는 것입니다. 내 코드는 문제를 해결하는 한 가지 방법입니다. 너도 정말 좋아 보인다. 왜 그것을 답변으로 게시하지 않습니까? –

관련 문제