AngularJS는 매우 강력한 프런트엔드 MVC 프레임워크입니다. AngularJS의 컨트롤러는 뷰 범위($scope)에 추가 기능을 추가하는 데 사용되는 함수입니다. 개체 및 사용자 정의 동작을 추가합니다.
새 컨트롤러를 만들 때 angleJS는 새 $scope 객체를 생성하여 이 컨트롤러에 전달하는 데 도움이 됩니다. AngleJS 애플리케이션의 모든 부분에는 최상위 범위인 상위 범위가 있습니다. app이 위치하고 해당 상위 범위는 $rootScope입니다.
각 $scope의 $root는 $rootScope를 가리키고 $cope.$parent는 상위 범위를 가리킵니다.
컨트롤러 간의 통신은 기본적으로 현재 컨트롤러가 위치한 $scope가 다른 컨트롤러의 $scope와 통신하는 방식입니다.
대개 3가지 해결 방법이 있습니다.
범위 상속 원칙을 사용하여 하위 컨트롤러는 상위 컨트롤러의 콘텐츠에 액세스합니다. AngleJS에서 이벤트를 사용합니다. 즉, 메시지 전달을 위해 $on, $emit, $broadcast를 사용합니다.
첫 번째 방법
즉, 범위는 특정 사용 제한이 있으며 범위를 중첩해야 합니다. 이 시나리오는 비교적 드물지만 이 방법이 더 간단하고 직접적입니다.
AngularJS에서는 기본적으로 현재 범위에서 속성을 찾을 수 없으면 상위 범위에서 검색됩니다. 찾을 수 없으면 $rootScope를 찾을 때까지 검색됩니다. $rootScope에서 찾을 수 없는 경우 프로그램은 계속 실행되지만 보기는 업데이트되지 않습니다.
예
자바스크립트
//Javascript app.controller('ParentController', function($scope) { $scope.person = {greeted: false}; }); app.controller('ChildController', function($scope) { $scope.sayHello = function() { $scope.person.name = 'Ari Lerner'; }; }); //HTML <div ng-controller="ParentController"> <div ng-controller="ChildController"> <a ng-click="sayHello()">Say hello</a> </div> {{ person }} </div> //result {"greeted":true, "name": "Ari Lerner"}
두 번째 방법
범위는 계층적이므로 범위 체인을 사용하여 이벤트를 전달할 수 있습니다.
이벤트를 전달하는 방법에는 두 가지가 있습니다. * $broadcast: 트리거된 이벤트는 전체 이벤트 시스템에 알리기 위해 아래로 전파되어야 합니다(모든 범위에서 이 이벤트를 처리할 수 있도록 허용). * $emit: 전역 모듈에 알림을 주고 싶다면 더 높은 수준의 범위(예: $rootscope)에 알려야 할 때 이벤트를 위쪽으로 전달해야 합니다.
이벤트 모니터링 범위에 $on을 사용하세요.
예
자바스크립트
app.controller('ParentController', function($scope) { $scope.$on('$fromSubControllerClick', function(e,data){ console.log(data); // hello }); }); app.controller('ChildController', function($scope) { $scope.sayHello = function() { $scope.$emit('$fromSubControllerClick','hello'); }; }); //HTML <div ng-controller="ParentController"> <div ng-controller="ChildController"> <a ng-click="sayHello()">Say hello</a> </div> </div>
여기서 또 이야기하고 싶은 문제는 이벤트 전파의 성능 문제입니다. $broadcast+$on 메서드가 모든 하위 범위에 알리면 여기서 성능 문제가 발생하므로 $emit+$on을 사용하는 것이 좋습니다. 성능을 더욱 향상시키기 위해서는 범위가 소멸될 때 정의된 이벤트 처리 함수를 함께 해제해야 합니다.
$emit+$on을 사용하려면 이벤트 리스너를 $rootScope에 바인딩해야 합니다. 예를 들면 다음과 같습니다.
자바스크립트
angular .module('MyApp') .controller('MyController', ['$scope', '$rootScope', function MyController($scope, $rootScope) { var unbind = $rootScope.$on('someComponent.someCrazyEvent', function(){ console.log('foo'); }); $scope.$on('$destroy', unbind); } ]);
근데 이 방법은 좀 번거롭고 여러 이벤트 처리 함수를 정의할 때 불편하니 개선해 보겠습니다
데코레이터를 사용하여 새 이벤트 바인딩 기능을 정의합니다.
자바스크립트
angular .module('MyApp') .config(['$provide', function($provide){ $provide.decorator('$rootScope', ['$delegate', function($delegate){ Object.defineProperty($delegate.constructor.prototype, '$onRootScope', { value: function(name, listener){ var unsubscribe = $delegate.$on(name, listener); this.$on('$destroy', unsubscribe); return unsubscribe; }, enumerable: false }); return $delegate; }]); }]);
그런 다음 컨트롤러에서 이벤트 핸들러 기능을 정의할 때:
자바스크립트
angular .module('MyApp') .controller('MyController', ['$scope', function MyController($scope) { $scope.$onRootScope('someComponent.someCrazyEvent', function(){ console.log('foo'); }); } ]);
이 방법을 적극 권장합니다
세 번째 방법
AngularJS의 서비스 싱글턴 모드 특성을 활용하여 서비스(service)는 애플리케이션의 전체 수명주기 동안 데이터를 유지하고 컨트롤러 간 통신하며 데이터 일관성을 보장하는 방법을 제공합니다.
일반적으로 우리는 애플리케이션이 데이터에 액세스하거나 원격으로 데이터와 상호 작용할 수 있는 인터페이스를 제공하기 위해 서버를 캡슐화합니다.
예
자바스크립트
var myApp = angular.module("myApp", []); myApp.factory('Data', function() { return { name: "Ting" } }); myApp.controller('FirstCtrl', function($scope, Data) { $scope.data = Data; $scope.setName = function() { Data.name = "Jack"; } }); myApp.controller('SecondCtrl', function($scope, Data) { $scope.data = Data; $scope.setName = function() { Data.name = "Moby"; } });
위 내용은 AngularJS 컨트롤러의 올바른 통신 방법입니다. 모두에게 도움이 되기를 바랍니다.