2014-10-20 2 views
1

특정 팩토리를 사용하여 특정 웹 서비스를 폴링합니다. 이 웹 서비스는 모든 데이터를 공장에서 업데이트하는 데 사용됩니다. 주 컨트롤러에서이 팩토리를 시작하고 팩토리 함수를 통해 범위 변수를 채 웁니다. 변수가 올바르게 초기화되고 화면에 올바른 데이터가 표시되지만 데이터를 자동으로 바인딩하는 데 어려움을 겪고 있습니다.각도 - 팩토리 데이터가 변경 될 때 범위 업데이트

추가 노트 편집 : 이 코드가 공장에있는 이유는 공장 데이터를 여러보기에서 사용할 계획이기 때문입니다.

App.factory('metrics', function($http, $q, $timeout){ 
    var service; 
    var users = [{laps:[]}]; 
    var updateMetrics = function(){ 
     //updates the users array in the factory 
    }; 
    service.load = function(){ 
     var deferred = $q.defer(); 

     $http.get('http://www.example.com/api/random').success(function(data) { 
      var temp_array = data.split("\n"); 
      updateMetrics(0, temp_array); 
      deferred.resolve({status: 'good'}); 
      $timeout(service.load,3000); 
     }); 
     return deferred.promise; 
    }; 

    service.lastLapInfo = function(){ 
     var lastlap = []; 
     for (var i=0; i<users.length;i++) 
     { 
      var lap = users[i].laps[users[i].laps.length-1]; 
      lastlap.push(lap); 
     } 
     return lastlap; 
    }; 
    return service; 
}); 

App.controller('mainController', function($scope, metrics) { 
    metrics.load().then(function(response){ 
     $scope.$watch(function() { return metrics.lastLapInfo() }, function (newVal, oldVal) { 
      if (newVal !=oldVal) 
      { 
       $scope.users=metrics.lastLapInfo(); 
      } 
     }); 
    }); 
}); 

내가 위를하려고 할 때, 나는 '10 $ 다이제스트에 도달() 반복 '라는 오류를 얻을 : 여기

는 내가 지금까지 가지고있는 것입니다. 시계 기능을 여러 번 호출하지 않기 때문에 가능한 방법을 모르겠습니다.

어떤 제안 (또는 다른 수단 내가 할 노력하고있어 달성하기 위해?)

+0

'$ service.load' (당신의 프로젝트에'service' 접두어'$')에 당신의 오타가 있습니까? –

+0

사과 - 프로젝트에서 구문이 정확하지만 복사/붙여 넣기 중에 문법이 엉망이어야합니다. 문제를 해결하기 위해 질문을 수정했습니다. – darudude

답변

2

100 % $watch를 사용하여 설정되지 않은 경우, 내가 선호하는 패턴이 (새로운 인스턴스를하지 바인딩하는 것입니다 참조) 모듈을 현재 범위로 가져오고 컨트롤러를 프로젝트의 뷰와 모델을 함께 연결하는 데 사용되는 구성 요소로 엄격하게 유지합니다. 이는 모듈간에 데이터를 조정하는 경우에도 $watch의 사용을 제외합니다. 나는 $rootScope$broadcast, $emit$on 메서드를 모듈/팩토리 (서비스로 전달한 후 $rootScope을 전달한 후 사용하는 것을 선호합니다. 모든 상황에서 작동 할 수도 있고 작동하지 않을 수도 있음). 비교적 느린 $watch 또는 $watchCollection 방법. 후자를 사용하면 내 안에 더럽다고 느끼지만 ...하지만 나는 빗 나간다.

상황에 따라 다음과 같이 작동합니까? $scope.metrics = angular.copy(metrics) 설정함으로써

App.factory('metrics', function($http, $q, $timeout){ 
    var service; 
    service.users = [{laps:[]}]; 
    service.updateMetrics = function(){ 
     // updates the users array in the current instance of `metrics` 
     // ex: 
     // this.users = updatedMetrics; 
     // don't do: 
     // service.users = updatedMetrics; 
    }; 
    service.load = function(){ 
     var deferred = $q.defer(); 

     $http.get('http://www.example.com/api/random').success(function(data) { 
      var temp_array = data.split("\n"); 
      this.updateMetrics(0, temp_array); 
      deferred.resolve({status: 'good'}); 
      $timeout(service.load,3000); 
     }.bind(this)); 
     return deferred.promise; 
    }; 

    service.lastLapInfo = function(){ 
     var lastlap = []; 
     for (var i=0; i<this.users.length;i++) 
     { 
      var lap = this.users[i].laps[this.users[i].laps.length-1]; 
      lastlap.push(lap); 
     } 
     return lastlap; 
    }; 
    return service; 
}); 

App.controller('mainController', function($scope, metrics) { 
    $scope.metrics = angular.copy(metrics); 

    $scope.metrics.load(); 

}); 

, 우리는 오히려 metrics ($scope.metrics = metrics)을 기준으로 설정 $scope.metrics보다 metrics의 새로운 인스턴스를 생성한다. 여기에는 동일한 모듈에 대한 참조가 아닌 $scope에 바인딩 된 객체가 완전히 새로운 객체이기 때문에 컨트롤러에서 동일한 모듈의 여러 인스턴스 (예 : $scope.foo = angular.copy(foo); $scope.bar = angular.copy(foo);)를 사용할 수 있다는 등 여러 이점이 있습니다.

또 다른 이점은 metrics의 인스턴스가 metrics에있는 메소드를 호출하여 metrics에 대한 변경을 컨트롤러의보기에 자동으로 적용 할 수 있습니다. angular.copy 또는 $.extend을 사용하지 않을 때이 문제를 해결하려고 할 때 자주 이상한 문제가 발생했습니다. 겉보기에 $scope에 첨부 된 참조 모듈에 대한 변경 사항이 항상 등록되지는 않았기 때문입니다.

+0

나는 정직하게 작동하는 옵션에 열려 있습니다. 코드를 살펴 봤지만이 경우 확장이 얼마나 작동하는지 잘 모르겠습니다. 모서리 문서를 읽는 것부터 시작해서 원본에서 대상으로 객체 복사를 확장하는 것 같습니다. 또한 위의 대답에서 추가 매개 변수 (true)가있는 것 같습니다. 무슨 일이 일어나고 있는지 간단히 요약 해 주시겠습니까? – darudude

+0

필자는 jQuery의'extend' 메소드 대신'angular.copy'를 사용하도록 코드를 변경했습니다.이 메소드는 완전히 지식이 있습니다.답변은 개요로 편집되었습니다. –

+1

+1을 위해 이미 존재하는 AngularJS eventBus ($ rootscope)를 활용합니다. – mccainz

관련 문제