html 중에 메뉴를 아래와 같이 만들었다 가정합니다.
index.html
<div class="btnClick" ng-controller='gnbNav' > <nav id="lnb"> <ul> <li ng-repeat='gnbMenu in gnbMenus' > <button ng-click="callProject()"> <div class="listNumber">{{gnbMenu.Num}}</div> <h2>{{gnbMenu.title}}</h2> <span>{{gnbMenu.date}}</span> </button> </li> </ul> </nav> </div>
그리고 메뉴 구조를 아래처럼 변수에 담아두겠습니다.
app.js
var gnbLoad = [ {Num : "2", title : "테스트2", date : "2015.8.1", url : "test2.html"}, {Num : "1", title : "테스트1", date : "2015.7.1", url : "test1.html"} ];
이렇게 만들어 놓는 이유는 외부에서 동적으로 저 안에 메뉴가 추가되거나 삭제 되면 반영이 될 수 있도록 하기 위함입니다.
다음은 js파일에 앱설정을 합니다.
app.js
var app = angular.module('rndApp',['ngRoute','ngAnimate']);
모듈 설정을 추가 합니다. 모듈은 라우터랑 애니메이션을 넣겠습니다.
이제 스크립트로 위 메뉴에 대한 기능 정의를 하겠습니다.
controller.js
app.controller('gnbNav', function($rootScope, $scope, $location){ $scope.gnbMenus = gnbLoad; // gnbNav 안의 메뉴 구성 $scope.callProject = function(e){ //ng-click으로 인한 액션 $location.path('/' + this.gnbMenu.Num); //경로를 변경함(config에서 인식하고 아래 컨트롤러'contentArea'에서 반응함) = 퍼말링크 만들기 var urlData = this.gnbMenu.url, viewMode = this.gnbMenu.viewmode; $rootScope.$broadcast('sendUrl', urlData, viewMode); //아래 컨트롤러'contentArea' 쪽으로 변수 전달을 위한 브로드케스트 } }); //gnbNav
여기서 중요한 것은 $rootScope.$broadcast 입니다. 다른 컨트럴에 변수를 전달하기 위한 것이죠.
클릭하면 이동시킬 url을 다른 컨트럴안의 함수를 실행시키기 위한 것입니다.
1. $http 활용
이 방법은 외부 xml이나 json 데이터를 불러와서 처리할 때 용이하게 사용되지만 외부 html 파일도 가져오는 방법도 가능합니다.
1-1 . config.js
먼저 라우터를 설정하는 config 스크립트 부터 작성하겠습니다.
app.config(['$routeProvider',function($routeProvider){ $routeProvider .when('/:link',{ }); }]);
1-2. index.html
그리고 html에 바인딩 시킬 위치를 만듭니다.
<section ng-controller="contentArea"> <div id="inc1"></div> </section>
기본적으로 바인딩 시킬 요소의 id만 있어도 됩니다.
제이쿼리로 간단하게 데이터를 찾아 넣을 선택자만 있으면 됩니다.
1-3. controller.js
app.controller('contentArea', function($scope, $location, $routeParams, $http){ $scope.$on('sendUrl',function(scope, getUrl, getViewMode){ $http({ method : 'GET', url : getUrl }).success( function(data, status, headers, config){ $('#inc1').empty().html(data); } ).error( function(data, status, headers, config){ console.log("error"); } ); }); });
contentArea의 컨트롤러를 추가합니다.
데이터를 불러올 때 성공일 경우 $('#inc1').empty().html(data) 위 삽입시킬 요소를 비운 뒤 그 안에 html로 바인딩 시키는 것입니다.
2. ng-include 활용
ng-include는 말 그대로 인클루드 입니다.
php와 같은 개발 언어로 웹사이트를 구축할 때 공통적으로 사용하는 헤더는 header.php로 두고 외부에서 불러와서 쓰고, 하단 공통된 정보도 footer.php라고 만들어서 인클루드해서 써서 헤더나 푸터 수정할 때는 로드 된 파일만 찾아가서 수정하면 인클루드 시켰던 모든 페이지들이 변경되게 운영하는 방법을 생각하시면 됩니다.
위 기능을 활용하여 하나의 요소 안에 $http 때처럼 클릭하면 해당 파일이 바인딩 되게 만들겠습니다.
2-1. config.js
app.config(['$routeProvider',function($routeProvider){ $routeProvider .when('/:link',{ }); }]);
라우터 설정은 $http때와 같습니다.
2-2. index.html
<section ng-controller="contentArea"> <div id="inc1" ng-include="template.includeLink1"></div> </section>
html도 $http때와 비슷하나 ng-include="template.includeLink1" 불러올 파일의 경로를 지정하는 ng-include 지시자를 추가합니다.
2-3. controller.js
app.controller('contentArea', function($scope, $location, $routeParams, $http){ $scope.$on('sendUrl',function(scope, getUrl, getViewMode){ $scope.template = { includeLink1 : getUrl }; }); });
$http 때 처럼 contentArea 컨트롤러를 추가합니다. $http 때 보다 간결해졌습니다.
$rootScope.$broadcast로 보내진 sendUrl을 받자마자 $scope.template의 includeLink1 값이 바뀌었기 때문에 실시간으로 적용된 것입니다.
ng-include는 ng-animate 모듈이 적용되기 때문에 전환되는 순간 ng-include지시자가 담긴 요소에 ng-enter, ng-leave와 같은 클래스들이 추가/제거 되는 현상을 발견하게 될 것입니다.
3. ng-view 활용
ng-view는 한 도큐먼트에 하나만 사용할 수 있게 되어 있습니다. 라우터를 감지하여 주소창에 노출된 주소에 의해 불러오는 파일을 정하고 또 불러오는 파일마다 컨트럴을 지정해서 사용할 수 있습니다.
3-1. config.js
app.config(['$routeProvider',function($routeProvider){ $routeProvider .when('/:link',{ templateUrl : function(params){ return gnbUrl; } }); }]);
$http 때와 달리 templateUrl이 추가되었고 고정 url이 아니라 동적 url이기 때문에 전역 변수 gnburl을 리턴받아 로드될 파일을 설정합니다.
3-2. index.html
<section ng-controller="contentArea"> <div id="inc1" ng-view></div> </section>
간단히 ng-view는 지시자만 있어도 됩니다.
3-3. controller.js
var gnbUrl; app.controller('gnbNav', function($rootScope, $scope, $location){ $scope.gnbMenus = gnbLoad; // gnbNav 안의 메뉴 구성 $scope.callProject = function(e){ //ng-click으로 인한 액션 $location.path('/' + this.gnbMenu.Num); //경로를 변경함(config에서 인식하고 아래 컨트롤러'contentArea'에서 반응함) = 퍼말링크 만들기 var urlData = this.gnbMenu.url, viewMode = this.gnbMenu.viewmode; gnbUrl = urlData; } }); //gnbNav
위 두 활용방법과 달리 contentArea 컨트롤러는 필요하지 않고 gnbNav 컨트롤러만 수정하면 됩니다.
$rootScope.$broadcast('sendUrl', urlData, viewMode) 가 사라지고 gnbUrl = urlData; 이 추가되었습니다.
그리고 컨트롤러 시작 전에 var gnbUrl;라고 전역변수를 지정해주면, ng-click이 발생될 때 $scope.callProject가 실행되어 gnbUrl에 로드할 파일을 담아둡니다.
그리고 $location.path의 변경으로 인해 config.js에서 라우터 감지를 하여 전역 변수 gnbUrl에 담긴 값을 가져와 로드할 파일로 설정하여 바인딩한 것입니다.