답변:
우선, 부모-자식 범위 관계가 중요합니다. 이벤트를 발생시킬 수있는 두 가지 가능성이 있습니다.
$broadcast
-이벤트를 모든 하위 범위로 하향 전달합니다.$emit
-범위 계층 구조를 통해 위쪽으로 이벤트를 전달합니다.컨트롤러 (범위) 관계에 대해서는 아무것도 모르지만 몇 가지 옵션이 있습니다.
의 범위는 경우 firstCtrl
의 부모 secondCtrl
범위는, 당신의 코드를 대체하여 작업을해야 $emit
으로 $broadcast
의 firstCtrl
:
function firstCtrl($scope)
{
$scope.$broadcast('someEvent', [1,2,3]);
}
function secondCtrl($scope)
{
$scope.$on('someEvent', function(event, mass) { console.log(mass); });
}
스코프간에 상위-하위 관계가없는 경우 $rootScope
컨트롤러에 주입 하고 모든 하위 범위 (예 :)로 이벤트를 브로드 캐스트 할 수 있습니다 secondCtrl
.
function firstCtrl($rootScope)
{
$rootScope.$broadcast('someEvent', [1,2,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]);
}
$rootScope
으로 서비스에 주입 하고 서비스에서 이벤트를 브로드 캐스트 할 수 있습니다.
$rootScope
있지만 서비스 $rootScope
에서 이벤트를 발생시키는 경우에도 이벤트가 계속 진행됨을 알고 싶습니다 $rootScope
. 왜냐하면 브로드 캐스터 / 이미 터가 리스너 (?)이기 때문에 $broadcast
계층 구조를 DOWN하고 $emit
UP 과 PER을 "UP"과 "DOWN"사이에서 겪는 경우 입니다. 이벤트가 모든 "UPWARD"및 모든 "DOWNWARD"범위에 대해 자동이지만 디스패처와 동일한 레벨에서만 '듣기'만하려면 어떻게해야합니까?
@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();
});
$rootScope
컨트롤러에 주입 해야합니다 (일반적으로 필요하지 않은 것). 그러나 또 다른 옵션 인 thx!
. $ emit 및. $ on 메소드를 사용하여 한 컨트롤러에서 다른 컨트롤러로 $ scope 객체를 보내려면 어떻게해야합니까?
$ scope를 포함하여 앱의 계층 구조 내에서 원하는 객체를 보낼 수 있습니다 .
다음은 브로드 캐스트 및 방출 작동 방식에 대한 간단한 아이디어 입니다.
아래 노드를 확인하십시오. 이 시나리오는 브로드 캐스트를 사용 하고 방출 합니다.
참고 : 이 예에서 각 노드의 수는 임의입니다. 그것은 쉽게 1 위가 될 수 있습니다. 두 번째; 또는 심지어 1,348의 숫자. 각 숫자는이 예의 식별자 일뿐입니다. 이 예제의 핵심은 Angular 컨트롤러 / 지시문의 중첩을 보여주는 것입니다.
3
------------
| |
----- ------
1 | 2 |
--- --- --- ---
| | | | | | | |
이 나무를 확인하십시오. 다음 질문에 어떻게 대답하십니까?
참고 : 이러한 질문에 대답하는 다른 방법이 있지만 여기서는 broadcast 및 emit에 대해 설명 합니다. 또한 아래 텍스트를 읽을 때 각 숫자에는 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 .
도움이 되었기를 바랍니다...
The event life cycle starts at the scope on which $broadcast was called. All listeners listening for name event on this scope get notified.
ctrl1을 ctrl3과 함께 ctrl2와 대화하도록 구현하면 나처럼 무한 루프가 발생합니다 $on('x', function(e, data) { $broadcast('x', data) })
. 방송하기 전에이 라인이 필요합니다. if (e.targetScope.$id === $scope.$id) { return; }
보내려면 $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};
});
<!DOCTYPE html>
<html>
<head>
<script src= "http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script>
var app = angular.module('MyApp',[]);
app.controller('parentCtrl',function($scope){
$scope.$on('MyEvent',function(event,data){
$scope.myData = data;
});
});
app.controller('childCtrl',function($scope){
$scope.fireEvent = function(){
$scope.$emit('MyEvent','Any Data');
}
});
</script>
</head>
<body ng-app="MyApp">
<div ng-controller="parentCtrl" ng-model="myName">
{{myData}}
<div ng-controller="childCtrl">
<button ng-click="fireEvent()">Fire Event</button>
</div>
</div>
</body>
</html>
범위를 사용하여 이벤트를 범위 하위 또는 상위로 전달하고 전달할 수 있습니다.
$ emit- 이벤트를 부모에게 전파합니다. 브로드 캐스트 -이벤트를 어린이에게 전파합니다. $ on-$ emit 및 $ broadcast에 의해 전파되는 이벤트를 청취하는 방법.
index.html 예 :
<div ng-app="appExample" ng-controller="EventCtrl">
Root(Parent) scope count: {{count}}
<div>
<button ng-click="$emit('MyEvent')">$emit('MyEvent')</button>
<button ng-click="$broadcast('MyEvent')">$broadcast('MyEvent')</button><br>
Childrent scope count: {{count}}
</div>
</div>
app.js 예제 :
angular.module('appExample', [])
.controller('EventCtrl', ['$scope', function($scope) {
$scope.count = 0;
$scope.$on('MyEvent', function() {
$scope.count++;
});
}]);
여기에 코드를 테스트 할 수 있습니다 : http://jsfiddle.net/zp6v0rut/41/
아래 코드는 이벤트가 상위 컨트롤러 (rootScope)로 전달되는 두 개의 하위 컨트롤러를 보여줍니다.
<body ng-app="App">
<div ng-controller="parentCtrl">
<p>City : {{city}} </p>
<p> Address : {{address}} </p>
<div ng-controller="subCtrlOne">
<input type="text" ng-model="city" />
<button ng-click="getCity(city)">City !!!</button>
</div>
<div ng-controller="subCtrlTwo">
<input type="text" ng-model="address" />
<button ng-click="getAddrress(address)">Address !!!</button>
</div>
</div>
</body>
var App = angular.module('App', []);
// parent controller
App.controller('parentCtrl', parentCtrl);
parentCtrl.$inject = ["$scope"];
function parentCtrl($scope) {
$scope.$on('cityBoom', function(events, data) {
$scope.city = data;
});
$scope.$on('addrBoom', function(events, data) {
$scope.address = data;
});
}
// sub controller one
App.controller('subCtrlOne', subCtrlOne);
subCtrlOne.$inject = ['$scope'];
function subCtrlOne($scope) {
$scope.getCity = function(city) {
$scope.$emit('cityBoom', city);
}
}
// sub controller two
App.controller('subCtrlTwo', subCtrlTwo);
subCtrlTwo.$inject = ["$scope"];
function subCtrlTwo($scope) {
$scope.getAddrress = function(addr) {
$scope.$emit('addrBoom', addr);
}
}
angularjs 이벤트 문서에 따르면 수신 측에는 다음과 같은 구조의 인수가 포함되어야합니다
@params
-이벤트에 대한 정보를 포함하는 이벤트 객체 인 {Object} 이벤트
-수신자가 전달한 {Object} args
$scope.$on('fooEvent', function (event, args) { console.log(args) });
코드에서
또한 다른 컨트롤러에서 공유 할 수있는 정보를 얻으려는 경우이를 달성 할 수있는 또 다른 방법이 있으며 각 서비스입니다. 서비스가 싱글 톤이므로 컨트롤러간에 정보를 저장하고 가져올 수 있습니다. 해당 서비스의 설정 기능, 이러한 기능 노출, 서비스에서 글로벌 변수 작성 및 정보 저장에 사용
가장 쉬운 방법 :
HTML
<div ng-app="myApp" ng-controller="myCtrl">
<button ng-click="sendData();"> Send Data </button>
</div>
자바 스크립트
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, $rootScope) {
function sendData($scope) {
var arrayData = ['sam','rumona','cubby'];
$rootScope.$emit('someEvent', arrayData);
}
});
app.controller('yourCtrl', function($scope, $rootScope) {
$rootScope.$on('someEvent', function(event, data) {
console.log(data);
});
});
</script>
$rootScope
피할 수있을 때 브로드 캐스트 / 방출에 사용하지 마십시오 .