본문 바로가기

AngularJS

14. $scope -2 ($scope에서 사용자 정의 이벤트 처리)

1. $scope에서 사용자 정의 이벤트 처리

 - AngularJS에서는 웹어플리케이션에 어플리케이션 이벤트를 정의하고 이런 이벤트 처리에 대한 메커니즘을 제공

 이러한 사용자 정의 이벤트는 모두 $scope 객체를 통하여 처리되는데 $scope 객체에서 특정 이벤트를 발생시키면 이벤트를 발생한 $scope 객체의 자식이나 

 부모 $scope에서 해당이벤트를 듣고 있다 처리할 수 있다.

 1) 이벤트를 발생시키는 API 

  ① $broadcast(이벤트명, 인자들...)  : 자식 $scope에게 특정 이벤트의 이름으로 주어진 데이터와 함께 이벤트를 발생시킨다.

   $emit(이벤트명, 인자들...)  : 부모 $scope에게 특정 이벤트의 이름으로 주어진 데이터와 함께 이벤트를 발생시킨다.


 - $emit과 $broadcast로 발생되는 이벤트는 모두 $on 메서드를 이용해 특정 이벤트 이름에 해당하는 이벤트 리스너 함수를 등록할 수 있다.

이렇게 등록된 이벤트 리스너는 이벤트 이름으로 이벤트가 발생하게 되면 해당 이벤트 리스터 함수가 호출된다.

이벤트 리스너 함수의 첫 번째 인자는 이벤트 객체이고 다음 인자는 $emit과 $broadcast로 이벤트 발생 시 전달하는 데이터가 된다.


<!DOCTYPE html>
<html ng-app="app">
<head>
<meta charset="UTF-8">
<style type="text/css">
.ng-scope{border: 1px solid red; padding: 5px}
.msg-list-area{margin: 10px; height: 400px; border: 1px solid black;}
</style>
<script type="text/javascript" src="js/lib/angular.js" ></script>
<script type="text/javascript">
angular.module('app', [])
.controller('mainCtrl', function($scope){
$scope.broadcast = function(noticeMsg){
$scope.$broadcast("chat:noticeMsg", noticeMsg);
$scope.noticeMsg = "";
};
})
.controller('chatMsgListCtrl', function($scope, $rootScope){
$scope.msgList = [];
$rootScope.$on("chat:newMsg", function(e, newMsg){
$scope.msgList.push(newMsg);
});
$scope.$on("chat:noticeMsg", function(e, noticeMsg){
$scope.msgList.push("[공지]"+noticeMsg);
});
})
.controller("chatMsgInputCtrl", function($scope){
$scope.submit = function(newMsg){
$scope.$emit("chat:newMsg", newMsg);
$scope.newMsg = "";
};
});
</script>
</head>
<body ng-controller="mainCtrl">
<input type="text" ng-model="noticeMsg">
<input type="button" value="공지 전송" ng-click="broadcast(noticeMsg)">
<div class="msg-list-area" ng-controller="chatMsgListCtrl">
<ul>
<li ng-repeat="msg in msgList track by $index">{{msg}}</li>
</ul>
</div>
<div class="ng-scope" ng-controller="chatMsgInputCtrl">
<input type="text" ng-model="newMsg">
<input type="button" value="전송" ng-click="submit(newMsg)">
</div>
</body>
</html>

 - 위 코드를 보면 맨위에 mainCtrl 컨트롤러 함수가 저으이되고 그 아래로 chatMsgListCtrl컨트롤러 함수와 chatMsgInputCtrl 컨트롤러 함수가 정의돼 있다.

각 컨트롤러와 연결된 DOM에는 각 컨트롤러가 생성하는 $scope 객체가 연결된다. 

그리고 chatMsgListCtrl과 chatMsgInputCtrl 컨트롤러 함수에 연결된 DMO이 모두 mainCtrl 컨트롤러 함수에 연결된 DOM의 자식이므로 두컨트롤러 함수의

함수의 $scope는 mainCtrl 컨트롤러 함수 $scope의 자식이 된다.


동작 순서

     1. <input type="text" ng-model="noticeMsg">에서 사용자가 입력한 메시지를 ng-click="broadcast(noticeMsg)" 을 통해 mainCtrl의 broadcast함수를 호출한다.

     2. broadcast 함수에서 $scope.$broadcast("chat:noticeMsg", noticeMsg) 호출하여 "chat:noticeMsg"이벤트 이름으로 사용자가 입력한 메시지 내용과 함께 이벤트를 발생시킨다.

3. 그러면 chatMsgListCtrl 컨트롤러 함수의 $scope 객체는 mainCtrl 컨트롤러 함수의 부모 $scope에서 발생한 "chat:noticeMsg" 이벤트를 듣고 있다가 공지사항 내용을 "[공지]"문자열과 결합하여 메시지 목록에 추가하고 이를 메시지 목록 화면에 반영한다.

4. chatMsgInputCtrl 컨트롤러 함수의 $scope 객체는 chatMsgListCtrl 컨트롤러 함수와 형제 관계이므로 chatMsgInputCtrl 컨트롤러 함수에서 $broadcast 이벤트가 발생하면 chatMsgListCtrl 컨트롤러 함수의 $scope가 이벤트 감지할 방법이 없다. 그래서 chatMsgInputCtrl 컨트롤러가 $rootScope까지 이벤트 전파하는 를 $emit 메서드를 이용해

"chat:newMsg" 이벤트를 전파한다.

5. chatMsgListCtrl 컨트롤러는 $rootScope를 주입받아 $rootScope에 $on 메서드를 이용해 "chat:newMsg" 이벤트에 대한 처리를 한다.

6. $rootScope.$on("chat:newMsg", function(e, newMsg) 가 실행되어 메시지 목록에 사용자가 입력한 메시지를 추가한다.