source

왜 if(!$scope)를 사용하는가.$$phase) $120.반패턴?

ittop 2023. 3. 13. 20:52
반응형

왜 if(!$scope)를 사용하는가.$$phase) $120.반패턴?

가끔 사용할 필요가 있습니다.$scope.$apply"이미 진행 중인 오류"를 발생시킬 수 있습니다.그래서 저는 이 문제를 해결할 방법을 찾기 시작했고 이 질문을 발견했습니다.각진JS : $scope 호출 시 이미 진행 중인 오류 $digest를 방지합니다.145달러단, 코멘트(및 각 Wiki)에서는 다음을 읽을 수 있습니다.

(!$scope)의 경우는 하지 말아 주세요.$$phase) $120.$125는 당신의 $125를 의미합니다.$syslog()가 콜스택 내에서 충분히 높지 않습니다.

이제 두 가지 질문이 있습니다.

  1. 왜 이게 안티패턴일까요?
  2. $scope를 안전하게 사용하려면 어떻게 해야 하나요?$140?

"digest already in progress" 오류를 방지하기 위한 또 다른 "솔루션"은 $timeout을 사용하는 것 같습니다.

$timeout(function() {
  //...
});

그렇게 가는 거야?더 안전한가요?그래서 진짜 질문은 다음과 같습니다."이미 진행 중인 다이제스트" 오류 가능성을 완전히 제거할 수 있는 방법은 무엇입니까?

PS: $scope만 사용하고 있습니다.동기화되지 않은 비동기 j 콜백의 $120.(제가 알기로는 $scope를 사용해야 하는 상황입니다.변경을 적용하고 싶은 경우 $125).

더 나는 한가 하는 을 풀 수.$scope.$apply'먹다

장황한 답변:

브라우저의 Javascript 실행 방법 때문에 두 개의 다이제스트 호출이 우연히 충돌할 가능성은 없습니다.

우리가 작성한 JavaScript 코드는 모두 한 번에 실행되는 것이 아니라 교대로 실행됩니다.이러한 각 턴은 처음부터 끝까지 중단 없이 실행되며 턴이 실행 중일 때 브라우저에서는 다른 아무 일도 일어나지 않습니다.(http://jimhoskins.com/2012/12/17/angularjs-and-apply.html)에서 입수).

따라서 "digest already in progress" 오류는 다음 한 가지 상황에서만 발생합니다.다른 $apply 내에서 $apply가 발행된 경우. 예:

$scope.apply(function() {
  // some code...
  $scope.apply(function() { ... });
});

이 상황은 순수한 비angularjs 콜백에서 $scope.apply를 사용하면 발생하지 않습니다(예:setTimeout따라서 다음 코드는 100% 방탄입니다.따라서,if (!$scope.$$phase) $scope.$apply()

setTimeout(function () {
    $scope.$apply(function () {
        $scope.message = "Timeout called!";
    });
}, 2000);

이것조차 안전합니다.

$scope.$apply(function () {
    setTimeout(function () {
        $scope.$apply(function () {
            $scope.message = "Timeout called!";
        });
    }, 2000);
});

안전하지 않은 것($timeout은 모든 angularjs 도우미와 마찬가지로 이미 콜을 하기 때문에)$scope.$apply( 님 : : ) 。

$timeout(function () {
    $scope.$apply(function () {
        $scope.message = "Timeout called!";
    });
}, 2000);

왜 '아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아,if (!$scope.$$phase) $scope.$apply()는 안티 패턴입니다.사용하시는 경우 필요 없습니다.$scope.$apply 으로 ada와 같이setTimeout예를들면.

상세한 것에 대하여는, http://jimhoskins.com/2012/12/17/angularjs-and-apply.html 를 참조해 주세요.

이치노$$ 단계를 확인해도 다이제스트가 폭발하는 것을 보았습니다.는 안 $$프레픽스

를 사용해 주세요.

 $scope.$evalAsync();

이는 Angular ^1.4에서 선호되는 방법이며 애플리케이션 층에 대한 API로 구체적으로 노출되기 때문입니다.

어떤 경우든 다이제스트가 진행 중이고 다른 서비스를 다이제스트에 푸시하면 이미 다이제스트가 진행 중인 오류만 표시됩니다.그러니 이걸 치료하려면 두 가지 방법이 있어폴링 등 진행 중인 다른 다이제스트를 확인할 수 있습니다.

첫 번째 것

if ($scope.$root.$$phase != '$apply' && $scope.$root.$$phase != '$digest') {
    $scope.$apply();
}

위의 조건이 참일 경우 $120을 적용할 수 있습니다.$140의 다른 사용자는 없습니다.

두 번째 해결책은 $120을 사용하는 것입니다.

$timeout(function() {
  //...
})

$120 실행이 완료될 때까지 다른 다이제스트가 시작되지 않습니다.

scope.$apply$digest 바인딩의 가 되는 2방향 데이터 바인딩

A $digest(정확한 $watch되어 있습니다.$scope값이 변경되었는지 여부를 평가하고 변경을 감지한 경우 보기를 업데이트하기 위해 필요한 단계를 수행합니다.

, 그럼 이제 ㅇㅇㅇㅇㅇㅇㅇ를 $scope.$apply"이미 진행 중"이라는 오류가 발생했기 때문에 $digest가 실행되고 있는 것은 분명합니다만,원인은 무엇입니까?

> every ans-- > 매 ans$http, repeat, show,이 ", "ng", ", ", ", ", "를 .$digest모든 비용 범위 중에서 가장 어려운 부분인 사이클.

즉, 페이지에 4개의 컨트롤러 또는 명령 A, B, C, D가 있다고 가정합니다.

/4가 경우$scope그러면 페이지에는 총 16개의 $190 속성이 표시됩니다.

「」를 경우$scope.$apply에서는, 「D」가 됩니다.$digestcycle ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★!sc $rootScope 、 opeoperootrootrootroot 。

답변-->단,$scope.$digest$digest4월 4일 D의 이 A,을 주지 에는 A, B, C를 사용합니다.$scope.$diges 않다$scope.$apply.

또는 으로 'ng-show/hide'가 트리거될 수 .$digest사용자가 이벤트를 실행하지 않은 경우에도 100개 이상의 속성을 순환합니다.

$timeout권장되는 방법입니다.

Web Socket에서 받은 데이터를 바탕으로 페이지의 항목을 변경해야 하는 시나리오입니다.또한 Angular 밖에 있기 때문에 $timeout이 없으면 뷰가 아닌 유일한 모델이 변경됩니다.Angular(각)$timeout기본적으로 Angular에게 다음 $digest 라운드에서 변경하라고 말하는 것입니다.

다음도 시도해봤는데 효과가 있어요.다른 점은 $timeout이 더 명확하다는 것입니다.

setTimeout(function(){
    $scope.$apply(function(){
        // changes
    });
},0)

매우 멋진 솔루션을 찾았습니다.

.factory('safeApply', [function($rootScope) {
    return function($scope, fn) {
        var phase = $scope.$root.$$phase;
        if (phase == '$apply' || phase == '$digest') {
            if (fn) {
                $scope.$eval(fn);
            }
        } else {
            if (fn) {
                $scope.$apply(fn);
            } else {
                $scope.$apply();
            }
        }
    }
}])

필요한 곳에 주입:

.controller('MyCtrl', ['$scope', 'safeApply',
    function($scope, safeApply) {
        safeApply($scope); // no function passed in
        safeApply($scope, function() { // passing a function in
        });
    }
])

언급URL : https://stackoverflow.com/questions/22346990/why-is-using-ifscope-phase-scope-apply-an-anti-pattern

반응형