동적으로 외부파일 불러와서 dom에 바인딩($http, ng-view, ng-include 3가지 활용)

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에 담긴 값을 가져와 로드할 파일로 설정하여 바인딩한 것입니다.

TOP