Pages

July 8, 2014

AngularJS에서 다른 Scope간 데이터를 공유하는 방법

AngularJS로 웹 어플리케이션을 개발하다보면 서로 다른 scope간 데이터를 공유해야만 하는 경우를 종종 마주치게 되는데 이번에는 크게 3가지 정도로 데이터를 공유하는 방법을 살펴보도록 한다.

Parent scope와 child scope간 데이터 공유

3Scope간 Parent-Child관계가 성립이 되는 경우 아래의 방법을 이용할 수 있다.
AngularJS에서 scope는 prototypically상속을 받게 되는데 즉 어떤 property가 childe scope에서 정의되지 않았을 경우 parent scope를 통해 접근이 가능하다. parent scope의 멤버 변수는 childe scope의 `$scope.$parent' property을 통해 접근할 수 있다.

JavaScript

function Parent($scope) {
    $scope.x = 5;
    $scope.y = 5;
}

function Child($scope) {
    $scope.modifyBothScopes = function() {
        $scope.$parent.x++;
    };
    $scope.modifyOnlyChildScope = function() {
        // 멤버 변수 "y"가 child scope에 생성된다. 따라서 이 경우
        // $scope.$parent.y++ 문장은 parent scope의 y값만을 변경한다.
        $scope.y++;
    };
}

HTML

<div ng-controller="Parent">
    parentX = {{x}}<br/>
    parentY = {{y}}<br/>
<div ng-controller="Child">
    childX = {{x}}<br/>
    childY = {{y}}<br/>
    <a ng-click="modifyBothScopes()">ModifyBothScopes</a><br/>
    <a ng-click="modifyOnlyChildScope()">modifyOnlyChildScope</a><br/>
</div>
</div>

아래의 경로를 통해 직접 확인해볼 수 있다.
http://jsfiddle.net/ramandv/JHwxP/

Service를 이용한 데이터 공유

서로 독립적인 두 controller사이에 데이터를 공유해야 할 필요가 있을 경우 AngularJS의 Service를 이용할 수 있다. 공유할 데이터 모델을 가진 Service를 생성하고 해당 Service를 데이터 공유가 필요한 Controller에 의존성주입으로 데이터 공유를 하는 방법이다.

아래의 예제에서 Service는 변수 x를 저장하기 위해 사용이 되었고 독립적인 controller들 간에 x값을 공유하여 사용할 수 있다.

JavaScript

angular.module('myApp', [])
    .service('myService', function() {
        var x = 5;
        return {
            increase: function() {
                x++;
            },
            getX: function() {
                return x;
            }
        };
    })
    .controller("ControllerA", function($scope, myService) {
        $scope.x = 1;
        $scope.incrementDataInService = function() {
            myService.increase();
        };
        $scope.getDataInService = function() {
            $scope.x = myService.getX();
        };
    })
    .controller("ControllerB", function($scope, myService) {
        $scope.x = 1;
        $scope.incrementDataInService = function() {
            myService.increase();
        };
        $scope.getDataInService = function() {
            $scope.x = myService.getX();
        };
    });

HTML

<div ng-app="myApp">
    <div ng-controller="ControllerA">
        ControllerA.X = {{x}}<br/>
        <a ng-click="incrementDataInService()">incrementDataInService</a><br/>
        <a ng-click="getDataInService()">getDataInService</a><br/>
    </div>
    <hr/>
    <div ng-controller="ControllerB">
        ControllerB.X = {{x}}<br/>
        <a ng-click="incrementDataInService()">incrementDataInService</a><br/>
        <a ng-click="getDataInService()">getDataInService</a><br/>
    </div>
</div>

아래의 경로를 통해 직접 확인해볼 수 있다.
http://jsfiddle.net/ramandv/kR859/

Service를 통해 공유된 데이터 변경을 모니터하기

어떤 경우 서비스에서 변경된 사항을 캐치해야 할 경우가 있다. 이 경우를 위해서 AngularJS에선 "$broadcast"를 준비 해 두었다. $broadcast를 통해 변경된 데이터를 리스너들에게 넘겨줄 수 있다.

아래의 예제에서 ControllerA와 ControllerB는 "XChanged"라는 이벤트를 모니터링하고 있고 "myService" Service는 x값이 변경되었을때 "XChanged"라는 이벤트를 실제 x값과 함께 broadcast하고 있음을 알 수 있다.

JavaScript

angular.module('myApp', [])
    .service('myService', function($rootScope) {
        var x = 5;
        return {
            increase: function() {
                x++;
                $rootScope.$broadcast('XChanged', x);
            }
        };
    })
    .controller("ControllerA", function($scope, myService) {
        $scope.x = 1;
        $scope.incrementDataInService = function() {
            myService.increase();
        };
        $scope.$on('XChanged', function(event, x) {
            $scope.x = x;
        };
    })
    .controller("ControllerB", function($scope, myService) {
        $scope.x = 1;
        $scope.incrementDataInService = function() {
            myService.increase();
        };
        $scope.$on('XChanged', function(event, x) {
            $scope.x = x;
        };
    });

HTML

<div ng-app="myApp">
    <div ng-controller="ControllerA">
        ControllerA.X = {{x}}<br/>
        <a ng-click="incrementDataInService()">incrementDataInService</a><br/>
        <a ng-click="getDataInService()">getDataInService</a><br/>
    </div>
    <hr/>
    <div ng-controller="ControllerB">
        ControllerB.X = {{x}}<br/>
        <a ng-click="incrementDataInService()">incrementDataInService</a><br/>
        <a ng-click="getDataInService()">getDataInService</a><br/>
    </div>
</div>

역시 아래의 경로를 통해 확인할 수 있다.
http://jsfiddle.net/ramandv/25CVc/

No comments:

Post a Comment