2013-12-09 2 views
3

각도 웹 애플리케이션에 socket.io 클라이언트를 사용하고 있습니다. 나는 그것을 서비스에서 감쌌다. 그러나 그것은 반드시 관심의 대상이 아닐 수도있다. 그러나 들어오는 데이터가 서비스를 사용하는 컨트롤러와 다른 범위에 있기 때문에 항상 $scope.$apply을 호출해야합니다. 더 나쁜 것은 내가 설명한 safeApply을 사용해야하는 몇 가지 상황 (연결/다시 연결 중)을 발견했습니다. here.

나는 이것이 Angular Anti-Pattern이라는 것을 알고 있지만,이 문제를 해결할 방법은 없습니다.

$scope.$apply/safeApply을 많이 사용하는 컨트롤러를 오염시키지 않는 (일반적으로 서비스 내부에서)이를 해결하는 일반적인 방법이 있습니까?

BR, 다니엘 여기

는 또한 작업,하지만 좋지 않아 일부 코드 :

귀하의 경우
angular.module('mean') 
    .controller('ConnectionStateController', function ($scope) { 
     $scope.safeApply = function (fn) { 
      var phase = this.$root.$$phase; 
      if (phase == '$apply' || phase == '$digest') { 
       if (fn && (typeof (fn) === 'function')) { 
        fn(); 
       } 
      } else { 
       this.$apply(fn); 
      } 
     }; 

     var socket = io.connect('http://localhost:3000'); 
     $scope.message = 'Not connected'; 
     socket.on('connect', function() { 
      $scope.safeApply(function() { 
       $scope.message = "Connected"; 
      }); 
     }); 
    }); 

답변

0

, 당신은 socket.io 작업은 항상가 비동기 적으로 실행되도록려고하고 있다는 것을 알고 그것은 valid place to use $scope.$apply (towards the bottom of the page)이됩니다.

나는 을 사용하지 않고 safeApply을 사용하고 명시 적으로 $scope.$apply을 호출하는 것이 좋습니다. safeApply을 사용하면 실제 구현 실수를 피할 수 있습니다. 또한 서비스에 코드를 래핑하는 경우 $rootScope을 서비스에 삽입하고 $rootScope.$apply에 비동기 함수를 호출 할 수 있습니다. 그러면 각 컨트롤러에서 $scope.$apply 번으로 전화하지 않아도됩니다.

+0

오. 나는 아직도 멍청이야. 결국 실제로 $ scope. $ apply를 사용하는 법을 모르겠습니다. 또한'$ rootScope'에 넣는 것도 좋은 대안이 될 것입니다. (여러분이 이것을 자주하는 것을 압니다.) 내부 범위의 속성에 의해 무시 될 수 있기 때문입니다. 맞습니까? – Daniel

0

나는 defer을 사용하는 실제 해결책이 있으므로 직접 질문에 답할 것입니다. 그럼에도 내가 제대로했는지 확신 할 수 없다. 이것은 컨트롤러가이 같은 서비스를 사용할 수 있습니다

angular.module('mean') 
    .factory('ConnectionService', function ($q, $timeout) { 
     var bindings = {}; 
     var socket = io.connect('http://localhost:3000'); 
     // catch all events by overriding the socket's $emit 
     var $emit = socket.$emit; 
     socket.$emit = function (event, obj) { 
      console.log('***', 'on', '"' + event + '"', obj); 
      if (bindings.hasOwnProperty(event)) { 
       bindings[event].notify(obj); 
      } 
      $emit.apply(socket, arguments); 
     }; 

     return { 
      socket: socket, 
      observe: function (event, callback) { 
       if (!bindings.hasOwnProperty(event)) { 
        bindings[event] = $q.defer(); 
       } 
       bindings[event].promise.then(null, null, function (data) { 
        callback.apply(this, [ data ]); 
       }); 
      } 
     }; 
    }); 

:

ConnectionService.observe('news', function (data) { 
    $scope.message = data; 
}); 

확실하지 않음을 그 멋진 솔루션의 경우, 또는 부작용이있는 경우, 있음을 나는 볼 수 없습니다 여기에 서비스입니다 아직.

BR, 다니엘