블로그 이미지
윤영식
Frontend Application Architecter, Full Stacker, KnowHow Dispenser and Bike Rider

Publication

Statistics Graph

Recent Comment

'Dependency Injection'에 해당되는 글 1

  1. 2013.04.27 [AngularJS] 웹 애플리케이션 견고하게 만드는 방법
2013.04.27 16:36 AngularJS/Concept

AngularJS에 구성 요소에 대한 Snippet을 살펴본다. 또한 jQuery와 통합하여 사용하는 방법을 알아보자 



1. 들어가기

  - Angular를 통해서 Client-Side에서 데이터와 애플리케이션 로직을 분리한다

  - 최초에 넣어야 할 라이브러리들 

<script type="text/javascript" src="/path/to/angular/angular.js"></script>

<script type="text/javascript" src="/path/to/angular/angular-resource.js"></script>



2. Module

  - 정의

    + Modules are used to fully encapsulate all the angular code of your application into one entry point

    + 컴포넌트와 같으면 Self living 할 수 있다

    + 큰 프로젝트를 할 때의 모듈 나누는 방법

  - 메인 레이아웃 파일에 다음과 코드를 넣는다

    + <html 태그에 넣거나 <body 에 넣거나 한다 

    + SPA를 한다면 아마도 <body> 태그 밑의 특정 부분이 Dynamic DOM 이 될 것이다 

<html data-ng-app="YOUR_APP_NAME">

또는

<html ng-app="YOUR_APP_NAME">


  - JavaScript에서 사용하기 

    + angular는 글로벌 변수이고, directive/controller/filter/service등을 만들기 위한 App 변수를 만들었다

    + ['ngResource']와 같이 의존하는 라이브러리를 설정한다  

var App = angular.module('YOUR_APP_NAME', ['ngResource']);



3. Binding, Expression

  - 양방향 data binding, 조건문, 반복문

  - {{ expression }} 데이터 표현

// html

<div class="records" data-ng-repeat="record in records | orderBy:orderProp">

  <h5> {{ record.title }} </h5>

</div>


// js 

$scope.records = [{ title : 'one' }, { title : 'two' }, { title : 'three' }]; 



4. Dependency Injection

  - 코드를 조직화 하고 테스트 가능하게 만들어준다

  - controllers, module configuraitons, directives, filters, resources, routes 들을 DI 할 수 있다 

// 메소드 파라미터로 DI를 해준다

var Ctrl = function($scope, $http, $location) {

  //now you can use any of the injected variables


  //to change the URL after something has happened then you can use $location

  $location.path('/path/to/new/page');

}

//and now the injection of the variables

Ctrl.$inject = ['$scope','$http','$location'];


  - DI에 대한 개념을 제대로 잡고 싶다면 보지타님의 동영상 보라



5. Routes

  - 요청 uri path와 controller를 맵핑하는 것이다 

// 모듈의 config 에서 정의한다 

// $routeProvider 서비스를 통하여 정의한다 

// uri path에 대하여 templateUrl 과 controller를 맵핑한다 

App.config(['$routeProvider', function($routes) {


  $route.when('/',{

    templateUrl : '/templates/home.html',

    controller : HomeCtrl

  });


  $route.when('/register',{

    templateUrl : '/templates/register.html',

    controller : RegisterCtrl

  });


  $routes.otherwise({

    redirectTo : '/'

  });


}]);



6. Controller & Scope

  - 컨트롤러는 $scope와 함께하여 데이터를 연동한다 

  - controller 만들기 (ng-app의 명칭 즉, 모듈명이 없을 경우)

    + $scope.title를 변경하면 angular는 데이터 변경을 모른다 

    + 하기와 같은 예제에서는 $scope.$apply() 가 필요하다 

    + $apply() 는 일반 JavaScript Context에서 수행되는 것을 AngularJS Context로 수행 되게 해준다 (필히 참조)

    + $apply, $digest, $$phase 란 무엇인가?

// angularjs 모듈에서 파생되지 않은 컨트롤러 펑션

var SomeCtrl = function($scope, $http, $location) {

  $scope.value = 'some value';

};

// controller에게 서비스를 주입하여 준다 (DI)

SomeCtrl.$inject = ['$scope','$http','$location'];


// html에서 {{ }} 를 설정

<div class="header">{{ title }}</div>


// 하기와 같이 설정을 하면 {{ title }} 이 자동으로 바뀌어야 한다  

$scope.title = 'this is awesome';


//if a scope digestion is already going on then it will get picked up and you won't

//have to call the $scope.$apply() method

// $apply를 호출하면 $digest cycle로 들어가고 model이 변화를 감지하여 $watch 에 등록된 expression의 변경을 수행한다

// 즉, view가 re-rendering 되는 것이다 

if(!$scope.$$phase) { //this is used to prevent an overlap of scope digestion

  $scope.$apply(); //this will kickstart angular to recognize the change

}


  - $scope는 $rootScope 상속한 것이다

    + 만일 전체 애플리케이션에서 $scope를 통하여 어떤 펑션을 사용하고 싶다면 하기와 같이 한다

    + 모듈이 로딩 될 때 config 와 run 이 자동 호출된다. run은 main메소드와 유사하다 (참조

App.run(['$rootScope', function($rootScope) {

  $rootScope.sharedFunction = function() { ... };

}]);


  - controller 사용하기 정식 방법 두가지 

    + html 태그안에서 ng-controller 통하여 설정

    + $routes의 controller 설정

// html

<div data-ng-controller="SomeCtrl">...</div>


// js

$routes.when('/some/path',{

  controller : Ctrl,

  templateUrl : '/templates/controller.html'

});



7. Services

  - 전체 애플리케이션에서 공유하는 것들

  - DI를 통하여 객체를 전달함 

//define the service

// App 모듈에 myService가 정의한 서비스의 명칭

App.factory('myService', ['myOtherService', '$location', function(myOtherService, $location) {

  return function(input) {

    //do something with the input using the myOtherService or the $location objects.

    return input;

  };

}]);


//use the service within the controller

// Controller에서 $scope와 myService DI하여 공유한다 

var HomeCtrl = function($scope, myService) {

  var input = '123';

  input = myService(input);

};

HomeCtrl.$inject = ['$scope','myService'];


//use the service a directive

// App 모듈에 directive를 정의한다. myService 서비스를 DI하여 공유한다 

App.directive('myDirective', ['myService',function(myService) {

  return {

    link: function($scope, element, attrs) {

      var input = '123';

      input = myService(input);

    }

  }

}]);



8. Models

  - RESTful Web Service를 호출을 위하여 7번의 서비스 개념으로 만들어 놓고 사용할 수 있다 

// ModelName이라고 서비스를 만든다

// $resource를 통하여 서버사이드로 호출한다 

App.factory('ModelName', ['$resource', function($resource) {

  $resource.url('/path/to/model/controller/:id',{

    id : '@id', //this binds the ID of the model to the URL param

  },{

    query : { method : 'GET', isArray : true }, //this can also be called index or all

    save : { method : 'PUT' }, //this is the update method

    create : { method : 'POST' },

    destroy : { method : 'DELETE' }

  }

}]);


// Controller 에서 ModelName 서비스를 DI 받아서 호출한다

var SomeCtrl = function($scope, $http, $location, ModelName) {

  //now you can use ModelName to do your business

};

SomeCtrl.$inject = ['$scope','$http','$location','ModelName'];


  - ModelName을 통하여 다음과 같이 사용할 수 있다 (연구필요)

    + 서비스를 CRUD query 형태로 만들어서 사용한다

    + Breeze.js 로 확장할 수도 있겠다 

//list all the records on the page

var results = ModelName.query({ search : 'all' }, onSuccessFn, onFailureFn);


//get a specific record

var record = ModelName.get({ id : 123 }, onSuccessFn, onFailureFn); //onSuccessFn and onFailureFn are optional callback functions where you can further customize the response


//create a new ModelName record

var record = new ModelName();


//update that record

record.someAttr = 'someValue';

record.$save();


//or if you prefer to submit your data in a different way

ModelName.save({

    id : record.id

  },{

  somePostObject : {

    attr1 : 'value',

    attr2 : 'value2'

  }

});


//destroy the record (and include a token)

record.destroy({ token : record.token });



9. Directives

  - HTML 코드를 통하여 만들어 놓은 플러그인과 링크를 설정해 주는 것이다. 애플리케이션내에서 블럭을 격리시켜준다. (그냥 컴포넌트 개념을 생각하며 되겠다. 화면 구성을 위하여 UI 컴포넌트 추가하는 것 처럼)

  - 웹앱을 구조화하는데 도움을 준다 

  - Plugin, Validation(유효성검사), Dynamic text properties 또는 i18n, l10n 에도 활용한다 

// link 는 Controller와 Directive가 $scope 를 통하여 데이터를 공유하는 중요 통로이다 

angular.directive('myDirective',function($compile) {

  return {

    templateUrl : '/path/to/some/template.html', //(optional) the contents of this template can be downloaded and constructed into the element

    replace : true, //whether or not to replace the inner data within the element

    link : function($scope, $element, attributes) { //this is where your magic happens

      $scope.title = '...';

    }

  };

});



10. Filters

  - 필터는 재사용 가능한 오퍼레이션이다 

  - binding operation에 내장되어 함께 수행된다 예) 정렬, 문자변형, Pagination 등

// App 모듈에서 myUppercase 명칭의 filter 정의  

App.filter('myUppercase', function(data) {

  for(var i=0; i < data.length; i++) {

    data[i].title = data[i].title.toUpperCase();

  }

  return data;

});


// html에서 사용하기 

<div data-ng-repeat="for record in records | filter:myUppercase">...</div>


// 또는 javascript 코드에서 호출가능

//be sure to inject the $filter object

var values = ['one','two','three'];

values = $filter('myUppercase')(values);



11. HTML5 Mode

  - angular app이 angular의 routing system 안에서 HTML5 history방식으로 관리되게 해준다 

  - 해당 코드만 넣으면 된다 

App.config(['$locationProvider', function($location) {

  $location.html5Mode(true); //now there won't be a hashbang within URLs for browers that support HTML5 history

}]);



12. jQuery 사용

  - 가장 간단하게 angular.js 스크립트 태그 전에 jQuery 태그를 먼저 위치시키면 된다

  - Angular.js는 jqLite를 기본 사용하나 jQuery가 먼저 설정되면 jQuery로 대체되어 사용한다 



<참조>

  - 원문 : use angularjs to power your web application

  - AngularJS 소개 ppt


저작자 표시 비영리 변경 금지
신고
posted by peter yun 윤영식
prev 1 next