[javascript] $ scope. $ emit 및 $ scope. $ on으로 작업

and 메소드를 $scope사용하여 한 컨트롤러에서 다른 컨트롤러로 객체를 보내려면 어떻게 해야합니까?.$emit.$on

function firstCtrl($scope) {
    $scope.$emit('someEvent', [1,2,3]);
}

function secondCtrl($scope) {
    $scope.$on('someEvent', function(mass) { console.log(mass); });
}

내가 생각하는 방식으로 작동하지 않습니다. 어떻게 $emit하고 $on사용할 수 있습니까?



답변

우선, 부모-자식 범위 관계가 중요합니다. 이벤트를 발생시킬 수있는 두 가지 가능성이 있습니다.

  • $broadcast -이벤트를 모든 하위 범위로 하향 전달합니다.
  • $emit -범위 계층 구조를 통해 위쪽으로 이벤트를 전달합니다.

컨트롤러 (범위) 관계에 대해서는 아무것도 모르지만 몇 가지 옵션이 있습니다.

  1. 의 범위는 경우 firstCtrl의 부모 secondCtrl범위는, 당신의 코드를 대체하여 작업을해야 $emit으로 $broadcastfirstCtrl:

    function firstCtrl($scope)
    {
        $scope.$broadcast('someEvent', [1,2,3]);
    }
    
    function secondCtrl($scope)
    {
        $scope.$on('someEvent', function(event, mass) { console.log(mass); });
    }
    
  2. 스코프간에 상위-하위 관계가없는 경우 $rootScope컨트롤러에 주입 하고 모든 하위 범위 (예 :)로 이벤트를 브로드 캐스트 할 수 있습니다 secondCtrl.

    function firstCtrl($rootScope)
    {
        $rootScope.$broadcast('someEvent', [1,2,3]);
    }
    
  3. 마지막으로 자식 컨트롤러에서 이벤트를 범위 내로 전달해야 할 때 사용할 수 있습니다 $scope.$emit. 범위가 범위의 firstCtrl상위 인 경우 secondCtrl:

    function firstCtrl($scope)
    {
        $scope.$on('someEvent', function(event, data) { console.log(data); });
    }
    
    function secondCtrl($scope)
    {
        $scope.$emit('someEvent', [1,2,3]);
    }
    

답변

@zbynour의 제안 된 옵션에 대한 더 나은 대안으로 4 번째 옵션을 제안합니다.

사용 $rootScope.$emit보다는 $rootScope.$broadcast없이 trasmitting 컨트롤러 수용의 관계. 그런 식으로 이벤트는 일련의 범위 내에서 유지 $rootScope.$$listeners되지만 $rootScope.$broadcast이벤트는 모든 하위 범위로 전파되며 대부분 해당 이벤트의 리스너가 아닐 것입니다. 물론 수신 컨트롤러의 끝에서는을 사용 $rootScope.$on합니다.

이 옵션을 사용하려면 컨트롤러의 rootScope 리스너를 삭제해야합니다.

var unbindEventHandler = $rootScope.$on('myEvent', myHandler);
$scope.$on('$destroy', function () {
  unbindEventHandler();
});


답변

. $ emit 및. $ on 메소드를 사용하여 한 컨트롤러에서 다른 컨트롤러로 $ scope 객체를 보내려면 어떻게해야합니까?

$ scope를 포함하여 앱의 계층 구조 내에서 원하는 객체를 보낼 수 있습니다 .

다음은 브로드 캐스트방출 작동 방식에 대한 간단한 아이디어 입니다.

아래 노드를 확인하십시오. 이 시나리오는 브로드 캐스트를 사용 하고 방출 합니다.

참고 : 이 예에서 각 노드의 수는 임의입니다. 그것은 쉽게 1 위가 될 수 있습니다. 두 번째; 또는 심지어 1,348의 숫자. 각 숫자는이 예의 식별자 일뿐입니다. 이 예제의 핵심은 Angular 컨트롤러 / 지시문의 중첩을 보여주는 것입니다.

                 3
           ------------
           |          |
         -----     ------
         1   |     2    |
      ---   ---   ---  ---
      | |   | |   | |  | |

이 나무를 확인하십시오. 다음 질문에 어떻게 대답하십니까?

참고 : 이러한 질문에 대답하는 다른 방법이 있지만 여기서는 broadcastemit에 대해 설명 합니다. 또한 아래 텍스트를 읽을 때 각 숫자에는 one.js, two.js, three.js와 같은 자체 파일 (직접, 컨트롤러)이 있다고 가정합니다.

노드 1 은 노드 3과 어떻게 통신합니까?

파일 one.js에서

scope.$emit('messageOne', someValue(s));

three.js 파일 -통신에 필요한 모든 하위 노드에 대한 최상위 노드.

scope.$on('messageOne', someValue(s));

노드 2는 노드 3과 어떻게 통신합니까?

파일 two.js에서

scope.$emit('messageTwo', someValue(s));

three.js 파일 -통신에 필요한 모든 하위 노드에 대한 최상위 노드.

scope.$on('messageTwo', someValue(s));

노드 3은 노드 1 및 / 또는 노드 2와 어떻게 통신합니까?

three.js 파일 -통신에 필요한 모든 하위 노드에 대한 최상위 노드.

scope.$broadcast('messageThree', someValue(s));

파일 one.js && two.js 에서 메시지를 잡으려는 파일 또는 둘 다.

scope.$on('messageThree', someValue(s));

노드 2는 노드 1과 어떻게 통신합니까?

파일 two.js에서

scope.$emit('messageTwo', someValue(s));

three.js 파일 -통신에 필요한 모든 하위 노드에 대한 최상위 노드.

scope.$on('messageTwo', function( event, data ){
  scope.$broadcast( 'messageTwo', data );
});

파일 one.js에서

scope.$on('messageTwo', someValue(s));

하나

이러한 중첩 된 자식 노드가 모두 이와 같이 통신하려고하면 많은 $ on , $ broadcast ‘s$ emit ‘s 가 빠르게 나타납니다 .

여기 내가 좋아하는 일이 있습니다.

상위 PARENT NODE ( 이 경우 3) 에서 상위 컨트롤러 일 수 있습니다.

따라서 파일 three.js에서

scope.$on('pushChangesToAllNodes', function( event, message ){
  scope.$broadcast( message.name, message.data );
});

이제 모든 하위 노드 에서 메시지 를 $ emit 하거나 $ on을 사용하여 잡기 만하면 됩니다 .

참고 : 일반적으로 $ emit , $ broadcast 또는 $ on 을 사용하지 않고 하나의 중첩 경로에서 대화하기가 매우 쉽습니다. 즉, 대부분의 사용 사례는 노드 1 이 노드 2 와 통신 하거나 그 반대로 통신 하려고 할 때 사용됩니다 .

노드 2는 노드 1과 어떻게 통신합니까?

파일 two.js에서

scope.$emit('pushChangesToAllNodes', sendNewChanges());

function sendNewChanges(){ // for some event.
  return { name: 'talkToOne', data: [1,2,3] };
}

three.js 파일 -통신에 필요한 모든 하위 노드에 대한 최상위 노드.

우리는 이미 이것을 기억 했습니까?

파일 one.js에서

scope.$on('talkToOne', function( event, arrayOfNumbers ){
  arrayOfNumbers.forEach(function(number){
    console.log(number);
  });
});

잡으려는 각 특정 값과 함께 $ on 을 사용해야 하지만 이제는 잡거나 브로드 캐스트 할 때 부모 노드 간격을 넘어서 메시지를 얻는 방법에 대해 걱정할 필요없이 모든 노드에서 원하는 것을 만들 수 있습니다. 일반 pushChangesToAllNodes .

도움이 되었기를 바랍니다…


답변

보내려면 $scope object한 컨트롤러에서 다른 컨트롤러, I 대해 논의 $rootScope.$broadcast하고 $rootScope.$emit그들이 가장 많이 사용되는 여기에.

사례 1 :

$ rootScope. $ 방송 :-

$rootScope.$broadcast('myEvent',$scope.data);//Here `myEvent` is event name

$rootScope.$on('myEvent', function(event, data) {} //listener on `myEvent` event

$rootScope리스너는 자동으로 삭제되지 않습니다. 를 사용하여 삭제해야합니다 $destroy. $scope.$on리스너 $scope가 자동으로 소멸 될 때, 즉 $ scope가 소멸되는 즉시 사용하는 것이 좋습니다 .

$scope.$on('myEvent', function(event, data) {}

또는,

  var customeEventListener = $rootScope.$on('myEvent', function(event, data) {

  }
  $scope.$on('$destroy', function() {
        customeEventListener();
  });

사례 2 :

$ rootScope. $ 방출 :

   $rootScope.$emit('myEvent',$scope.data);

   $rootScope.$on('myEvent', function(event, data) {}//$scope.$on not works

$ emit과 $ broadcast의 주요 차이점은 생성 된 이벤트가 스코프 트리를 통해 내려 가지 않기 때문에 $ rootScope. $ on을 사용하여 $ rootScope. $ emit 이벤트를 수신해야한다는 것입니다. .
이 경우에도 $ broadcast의 경우와 같이 리스너를 삭제해야합니다.

편집하다:

나는 사용하는 $rootScope.$broadcast + $scope.$on것이 아니라 사용 하는 것을 선호 합니다
$rootScope.$emit+ $rootScope.$on. $rootScope.$broadcast +
$scope.$on
콤보는 성능에 심각한 문제가 발생할 수 있습니다. 이벤트가 모든 범위에서 버블 링되기 때문입니다.

편집 2 :

이 답변에서 해결 된 문제는 angular.js 버전 1.2.7에서 해결되었습니다. $ broadcast는 이제 등록되지 않은 범위에서 버블 링을 피하고 $ emit만큼 빠르게 실행됩니다.


답변

동일한 앱에서 컨트롤러간에 이벤트를 보내고 캡처하려면 $ rootScope를 사용해야합니다. 컨트롤러에 $ rootScope 종속성을 삽입하십시오. 다음은 실제 예입니다.

app.controller('firstCtrl', function($scope, $rootScope) {
        function firstCtrl($scope) {
        {
            $rootScope.$emit('someEvent', [1,2,3]);
        }
}

app.controller('secondCtrl', function($scope, $rootScope) {
        function secondCtrl($scope)
        {
            $rootScope.$on('someEvent', function(event, data) { console.log(data); });
        }
}

$ scope 객체에 연결된 이벤트는 소유자 컨트롤러에서만 작동합니다. 컨트롤러 간의 통신은 $ rootScope 또는 Services를 통해 수행됩니다.


답변

약속을 반환하는 컨트롤러에서 서비스를 호출 한 다음이를 컨트롤러에서 사용할 수 있습니다. 추가로 사용 $emit하거나 $broadcast다른 컨트롤러에 알려줍니다. 제 경우에는 서비스를 통해 http 호출을해야하므로 다음과 같이했습니다.

function ParentController($scope, testService) {
    testService.getList()
        .then(function(data) {
            $scope.list = testService.list;
        })
        .finally(function() {
            $scope.$emit('listFetched');
        })


    function ChildController($scope, testService) {
        $scope.$on('listFetched', function(event, data) {
            // use the data accordingly
        })
    }

내 서비스는 다음과 같습니다

    app.service('testService', ['$http', function($http) {

        this.list = [];

        this.getList = function() {
            return $http.get(someUrl)
                .then(function(response) {
                    if (typeof response.data === 'object') {
                        list = response.data.results;

                        return response.data;
                    } else {
                        // invalid response
                        return $q.reject(response.data);
                    }

                }, function(response) {
                    // something went wrong
                    return $q.reject(response.data);
                });

        }

    }])


답변

이것은 내 기능입니다.

$rootScope.$emit('setTitle', newVal.full_name);

$rootScope.$on('setTitle', function(event, title) {
    if (scope.item)
        scope.item.name = title;
    else
        scope.item = {name: title};
});