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

Publication

Statistics Graph

Recent Comment

2013.11.27 04:20 My Projects/BI Dashboard

Angular.js에서 Controller는 View DOM객체의 표현을 담당한다면 Service 모듈은 View단에 표현되는 NonVisible한 비즈니스 업무 데이터를 담당한다. 이전 블로그까지 모든 데이터 핸들링은 Controller에 담겨 있었는데 이를 Service 모듈로 분리 래팩토링 해보자. 또한 모듈분리를 하면서 $http를 추상화한 $resource를 사용해 보자 




1. factory vs service 무엇을 쓸까? (참조)

  - <module>.factory는 객체를 new 해서 return 해 주어야 한다. 

    따라서 별도의 function을 정의하고 해당 펑션을 new해서 return하는 구조일 때 사용

  - <module>.service는 function의 내용을 정의하고 new한 객체를 return할 필요가 없다 

  - <module>.factory 는 공통된 것을 function으로 이미 만들어 놓은 것을 사용할 때. 즉, 공통 모듈 <Module>Svc 에 생성

  - <module>.service 는 업무적으로 $resource/$http 이용하여 RESTful API 호출할  때. 즉 업무 모듈 <Module>Biz 에 생성



2. $resource 사용하기 

  - $resource 객체는 RESTful 클라이언트 애플리케이션 개발을 위한 $http 상위 레벨의 서비스이다

  - http에 대한 보다 정교한 header configuration이 가능하다

  - resource interceptors 가 있다

  - 보다 향상된 promises api를 제공한다 

  - API

// 사용법

$resource(url[, paramDefaults][, actions]);


// 의미 

- url

  string 이고, /user/:username 처럼 :<param> 형태로 입력가능하다. 전체 url을 넣어도 됨 


- paramDefaults 

  url parameters object 이고, /path/:verb 일때 파라미터값이 {verb:'greet', name:'dowon'} 이면

  url 결과는 /path/greet?name=dowon 으로 간다. @가 앞에 붙으면 전달하는 객체(json)에서 값을 추출하여 대입한다

 예) 

  var User = $resource('/user/:userId', {userId:'@id'});

  var user = User.get({userId:123}, function() {

     user.abc = true;

     user.$save();

  });


- actions 

  object.<object> 이고, $http.config의 action 을 상속받으며 사용자 정의하여 action을 추가할 수 있다.

  형식)

  {action1: {method:?, params:?, isArray:?, headers:?, ...},

   action2: {method:?, params:?, isArray:?, headers:?, ...},

   ...}


- 리턴타입

  기본적으로 resource에서 제공하는 action과 사용자 정의 action을 담아서 리턴한다 

  기본 action)

{ 'get':    {method:'GET'},

  'save':   {method:'POST'},

  'query':  {method:'GET', isArray:true},

  'remove': {method:'DELETE'},

  'delete': {method:'DELETE'} };



3. $resource 공통 모듈 만들기

  - $resource의 기본 action을 보면 'update': {method:'PUT'} 이 존재하지 않는다. 이를 custom action으로 포함시키고 공통 모듈로 만들어 보자. 

  - 공통 모듈을 만들기 전에 ngResource를 추가해야 한다. 애플리케이션에 없다는 다음과 과정을 거친다 

// bower로 angular resource 설치 및 bower.json에 추가 

$ bower install angular-resource --save


// index.html 에 추가 

<!-- build:js scripts/core.js -->

    <script src="bower_components/jquery/jquery.js"></script>

    <script src="bower_components/jquery-migrate/jquery-migrate.min.js"></script>

    <script src="bower_components/angular/angular.js"></script>

    <script src="bower_components/angular-route/angular-route.js"></script>

    <script src="bower_components/angular-resource/angular-resource.js"></script>

    <script src="bower_components/angular-cookies/angular-cookies.js"></script>

    <script src="bower_components/angular-sanitize/angular-sanitize.js"></script>

<!-- endbuild --> 


// ngResource가 필요한 모듈에 추가하기  

var DashboardApp = angular.module('DasbhoardApp', [

  'ngRoute',                                                  

  'ngCookies',

  'ngResource',

  'ngSanitize',

  'DasbhoardApp.CommonCtrl',

  'DasbhoardApp.RestTestBiz',

]);

  - $resource를 이용하여 공통 모듈을 만들어 보자 

// common/services/RestfulSvc.js 파일을 생성한다 

'use strict';

// 모듈 명칭 정의

var RestfulSvc = angular.module('DasbhoardApp.RestfulSvc', []);


RestfulSvc.factory('RestfulSvcApi', ['$resource', function ($resource) {

/**

* Restful API version. it must be attached the called url.

*/

var prefixUrl = '/api/v1';

/**

* @domain : biz object ex) person

* @key : biz object id ex) persion id is 123

* @action : server action name. if it exist, you can define or not.

* ex) http://www.bennadel.com/blog/2433-Using-RESTful-Controllers-In-An-AngularJS-Resource.htm

* add a update action for method of PUT

*/

return $resource( 

                           // 호출하는 url 형식

    prefixUrl + '/:domain/:key/:action',

                           // 호출 url 형식의 :domain :key :action 에 동적으로 받게 되는 파라미터

   {

    domain: "@domain",

    key: "@key",

    action: "@action"

   },

                            // 추가 action들 one, all, update 

   {

     one: { method: 'GET', isArray: false },

     all: { method: 'GET', isArray: true },

      update: {method:'PUT'}

    }

   );

}]);


// 새롭게 서비스 공통 모듈을 생성하였으니 index.html 과 DashboardApp 모듈에 추가한다 
// index.html 에서 
    <script src="scripts/common/controllers/CommonCtrl.js"></script>
    <script src="scripts/common/services/RestfulSvc.js"></script>

// DashboardApp.js 에서 
var DashboardApp = angular.module('DasbhoardApp', [
  'ngRoute',                                                  
  'ngCookies',
  'ngResource',
  'ngSanitize',
  'DasbhoardApp.CommonCtrl',
  'DasbhoardApp.RestTestBiz',
  'DasbhoardApp.RestfulSvc'
]);

 


4. Controller에 Service 모듈의 서비스 호출하기 

  - $http 방식을 $resource에 대한 추상 모듈 서비스로 대체한다

  - 기존의 RestTestBiz.js의 "RestTestBiz.personCtrl" 컨트롤러 로직을 리팩토링한다 

'use strict';

// 의존하는 모듈 주입

var RestTestBiz = angular.module('DasbhoardApp.RestTestBiz', ['DasbhoardApp.RestfulSvc']);


// 사용할 모듈의 서비스 주입 

RestTestBiz.controller('RestTestBiz.personCtrl', ['$scope', 'RestfulSvcApi', function ($scope, RestfulSvcApi) {


  var bizDomain = 'person';

  var load = function () {

    console.log('before calling...');

       // 사용자 정의 액션 all 호출 

    RestfulSvcApi.all(

    // param key domain의 값인 bizDomain는 @domain에 맵핑된다 

    { domain: bizDomain },

    // success

    function (response) {

    $scope.persons = response;

    console.log('persons is ', $scope.persons);

    }, 

    // error

    function (response) {

    });

     };


  load();


  $scope.save = function () {

  console.log('Save Person : ', $scope.person);

  RestfulSvcApi.save(

                        // 파라미터를 열거하면 하나의 json 객체로 합쳐준다 

  { domain: bizDomain }, $scope.person,

  function(response) { load(); },

  function(response) {}

  );

  };


  $scope.update = function () {

  console.log('Update Person : ', $scope.person);

  RestfulSvcApi.update(

  { domain: bizDomain }, $scope.person ,

  function(response) { load(); },

  function(response) {}

  );

  };


  $scope.deletePerson = function(personId) {

  console.log('Delete Person : ', personId);

  RestfulSvcApi['delete'](

  { domain: bizDomain, key: personId }, 

  function(response) { load(); },

  function(response) {}

  );

  };


}]);

  - RestfulSvcApi 와 같은 모듈 서비스를 해주는 추상화 공개 모듈이 존재한다. (참조)

    + Restangular

    + ModelCore

    + Angular-ServiceStack

    + Angular-ActiveRecord

    + Breezejs


  * 소스 : https://github.com/ysyun/SPA_Angular_SpringFramework_Eclipse_ENV/tree/feature_angular_service



<참조>

  - Angular.js v1.2 에서 향상된 내역들

  - ngResource를 통하여 트위터 연동하기 예제

  - $resource를 통한 RESTful API 구현하기 (필독)

  - rest 스타일의 ORM 모듈들

저작자 표시 비영리 변경 금지
신고
posted by peter yun 윤영식
2013.08.22 15:36 AngularJS/Concept

AngularJS의 서비스 종류는 여러가지가 있습니다. Factory만 알았다면 Costant, Value, Provider 그리고 서비스의 확장 방법등에 대해 알아보자. "AngularJS Service is an Application Brain"



1. 개념

  - 서비스는 여러 종류가 있다

  - 항시 Singleton 이다. 즉, 하나의 Instance만 존재한다 



2. Constant

  - 공통으로 사용하는 환경값을 지정할 때 상수를 지정한다 

  - 사용자 정의 Directive에서 환경값을 가져다 쓰고 싶을 때 유용하다

// script 

app = angular.module("app", []);


app.controller('MainCtrl', function($scope, fooConfig) {

  $scope.fooConfig = fooConfig;

});


app.constant('fooConfig', {

  config1: true,

  config2: "Default config2"

});


// html

<!DOCTYPE html>

<html ng-app="app">

<head>

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>

<meta charset=utf-8 />

<title>JS Bin</title>

</head>

  <body ng-controller="MainCtrl">

    config1: {{fooConfig.config1}}

    <br />

    config2: {{fooConfig.config2}}

  </body>

</html>



3. Value

  - Value Service는 Constant Service와 유사하지만 최초 한번은 변경을 할 수 있다. Factory 서비스의 작은 동생뻘이다 

  - Directive에서 사용하기 유용하다 

  - Value를 가지고 계산할 수는 없다 

// script 

app = angular.module("app", []);


app.controller('MainCtrl', function($scope, fooConfig) {

  $scope.fooConfig = fooConfig;

  // 최초 한번의 변경이 가능

  angular.extend(fooConfig, {config3: "I have been extended"}); 

});


app.value('fooConfig', {

  config1: true,

  config2: "Default config2 but it can changes"

});


// html 

<!DOCTYPE html>

<html ng-app="app">

<head>

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>

<meta charset=utf-8 />

<title>JS Bin</title>

</head>

  <body ng-controller="MainCtrl">

    config1: {{fooConfig.config1}}

    <br />

    config2: {{fooConfig.config2}}

    <br />

    config3: {{fooConfig.config3}}

  </body>

</html>



4. Factory

  - 가장 일반적으로 사용하는 서비스 종류이다 

  - 팩토리는 어떤 형태의 데이터타입이라도 리턴할 수 있다. 리턴된 오브젝트를 가지고 작업을 한다 

  - 단, 리턴된 오브젝트의 값을 변경하면 해당 팩토리의 인스턴스를 사용하는 모든 곳에 변경값이 반영된다 

  - Revealing Module Pattern 식으로 작성을 한다 

// script 

app = angular.module("app", []);

app.controller('MainCtrl', function($scope, foo) {

  $scope.foo = foo;

});


// revealing module pattern 방식의 팩토리 서비스

app.factory('foo', function() {

  var thisIsPrivate = "Private";

  function getPrivate() {

    return thisIsPrivate;

  }

  return {

    variable: "This is public",

    getPrivate: getPrivate

  };

});


// html

<!DOCTYPE html>

<html ng-app="app">

<head>

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>

<meta charset=utf-8 />

<title>JS Bin</title>

</head>

  <body ng-controller="MainCtrl">

    public variable: {{foo.variable}}

    <br />

    private variable (through getter): {{foo.getPrivate()}}

  </body>

</html>



5. Service 

  - "service" service는 Factory service와 유사사지만 생성자명칭(== 서비스명칭)을 넘기면 자동으로 new를 통하여 생성된다 

    즉, Factory 처럼 오브젝트의 리턴이 필요없다 

  - 하기 예는 완전히 동일하다. 주의 할 것은 factory안에서 또는 service사용시 new을 여러번 하여도 반드시 한번만 인스턴스화 한다

    즉, Singleton 패턴으로 객체 하나만이 생성된다 

// script 

app = angular.module("app", []);


// Service를 통해서 생성 

app.controller('MainCtrl', function($scope, foo) {

  $scope.foo = foo;

});


app.service('foo', function() {

  var thisIsPrivate = "Private";

  this.variable = "This is public";

  this.getPrivate = function() {

    return thisIsPrivate;

  };

});


// Factory를 통해서 생성 : MainCtrl 에서 foo 파라미터 값과 하위 로직을 foo2로 바꿔도 동일 결과 

app.controller('MainCtrl', function($scope, foo2) {

  $scope.foo = foo2;

});


app.factory('foo2', function() {

  return new Foobar();

});


function Foobar() {

  var thisIsPrivate = "Private";

  this.variable = "This is public";

  this.getPrivate = function() {

    return thisIsPrivate;

  };

}


// 또는 펑션을 넘길 수도 있다 : : MainCtrl 에서 foo 파라미터 값과 하위 로직을 foo3로 바꿔도 동일 결과 

app.controller('MainCtrl', function($scope, foo3) {

  $scope.foo = foo3;

});


app.service('foo3', Foobar);


// html 

<!DOCTYPE html>

<html ng-app="app">

<head>

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>

<meta charset=utf-8 />

<title>JS Bin</title>

</head>

  <body ng-controller="MainCtrl">

    public variable: {{foo.variable}}

    <br />

    private variable (through getter): {{foo.getPrivate()}}

  </body>

</html>

 


6. Provider

  - Provider는 factory의 큰형님 뻘이다 

  - $get fuction을 가지고 있어야 한다. 만일 Provider 명칭이 foo이고 controller에 inject될 때 실제는 $get function의 결과값이 inject되는 것이다. 왜 factory로 사용하면 간편한데 굳이 이렇게 할까?

  - 이유인즉슨, config function을 통해서 provide에 대한 환경설정을 할 수 있기 때문이다 

  - 예를 보자 

    1) thisIsPrivate 변수가 $get 펑션 밖에 위치한다 

    2) 따라서 setPrivate 메소드를 통하여 thisIsPrivate 변수값을 변경할 수 있다 

    3) 이런게 하는 이유는 우리가 필요로 하는 다양한 환경값을 바꾸어서 환경설정을 하고 싶기 때문이다

    4) Provider명칭이 'foo' 이므로 app.config 에서 'fooProvider' 명을 준다 

// script 

app = angular.module("app", []);

app.controller('MainCtrl', function($scope, foo) {

  $scope.foo = foo;

});


app.provider('foo', function() {

  var thisIsPrivate = "Private";

  return {

    setPrivate: function(newVal) {

      thisIsPrivate = newVal; 

    },

    

    $get: function() {

      function getPrivate() {

        return thisIsPrivate;

      }


      return {

        variable: "This is public",

        getPrivate: getPrivate

      };

    } 

  };

});


app.config(function(fooProvider) {

  fooProvider.setPrivate('New value from config');

});


// html 

<!DOCTYPE html>

<html ng-app="app">

<head>

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>

<meta charset=utf-8 />

<title>JS Bin</title>

</head>

  <body ng-controller="MainCtrl">

    public variable: {{foo.variable}}

    <br />

    private variable (through getter): {{foo.getPrivate()}}

  </body>

</html>



7. Decorator (보너스1)

  - 기존 서비스에 새로운 펑션을 넣고 싶을 경우 사용한다

  - 예를 보자 

    1) $provide는 모든 서비스들을 내부적으로 생성할 때 사용한다 

    2) $provide.decorator 를 통해서 서비스를 확장할 수 있다. 

        첫번째 인자는 서비스 명칭, 두번째는 콜백으로 서비스 인스턴스인 $delegate을 받는다 

    3) $delegate에 greet 라는 메소드를 확장 정의 한다 

    4) 만일 3rd party 라이브러리 사용시 확장하고 싶을 경우 decorator를 사용한다 

// script 

app = angular.module("app", []);


app.controller('MainCtrl', function($scope, foo) {

  $scope.foo = foo;

});


app.factory('foo', function() {

  var thisIsPrivate = "Private";

  function getPrivate() {

    return thisIsPrivate;

  }

  return {

    variable: "This is public",

    getPrivate: getPrivate

  };

});


app.config(function($provide) {

  $provide.decorator('foo', function($delegate) {

    $delegate.greet = function() {

      return "Hello, I am a new function of 'foo'";

    };

    

    return $delegate;

  });

});


// html 

<!DOCTYPE html>

<html ng-app="app">

<head>

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>

<meta charset=utf-8 />

<title>JS Bin</title>

</head>

  <body ng-controller="MainCtrl">

    public variable: {{foo.variable}}

    <br />

    private variable (through getter): {{foo.getPrivate()}}

    <br />

    greet: {{foo.greet()}}

  </body>

</html>



8. 새로운 인스턴스 생성하기 (보너스2)

  - 팩토리 메소드를 두어서 호출시 마다 무언가 새로 생성하고 싶을 경우 사용한다 

  - 예를 보자 

    1) Function 1급 class인 Person을 만든다 

    2) MainCtrl, SecondCtrl 각각 getById(1) 을 호출하지만 서로 다른 인스턴스가 전달되었다

    3) "Update It" 버튼을 클릭하면 두번째 열만 "Dave - Canada" 로 바뀜을 확인 할 수 있다 

// script 

app = angular.module('app', []);

app.controller('MainCtrl', function($scope, personService) {

  $scope.aPerson = Person.getById(1);

});

app.controller('SecondCtrl', function($scope, personService) {

  $scope.aPerson = Person.getById(1);

  $scope.updateIt = function() {

    $scope.aPerson.update();

  };

});


// Our class

function Person( json ) {

  angular.extend(this, json);

}


Person.prototype = {

  update: function() {

    // Update it (With real code :P)

    this.name = "Dave";

    this.country = "Canada";

  }

};


Person.getById = function( id ) {

  // Do something to fetch a Person by the id

  return new Person({

    name: "Jesus",

    country: "Spain"

  });

};


// Our factory

app.factory('personService', function() {

  return {

    getById: Person.getById

  };

});


// html

<!DOCTYPE html>

<html ng-app="app">

<head>

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>

<meta charset=utf-8 />

<title>JS Bin</title>

</head>

  <body>

    <p ng-controller="MainCtrl">{{aPerson.name}} - {{aPerson.country}}</p>

    <div ng-controller="SecondCtrl">

      {{aPerson.name}} - {{aPerson.country}}

      <button ng-click="updateIt()">Update it</button>

    </div>

  </body>

</html>

  - 위의 script 코드를 CoffeeScript로 하면 class 표현을 쉽게 할 수 있다 

app.controller 'MainCtrl', ($scope, personService) -> $scope.aPerson = personService.getById(1) app.controller 'SecondCtrl', ($scope, personService) -> $scope.aPerson = personService.getById(2) $scope.updateIt = () -> $scope.aPerson.update() class Person constructor: (json) -> angular.extend @, json update: () -> @name = "Dave" @country = "Canada" @getById: (id) -> new Person name: "Jesus" country: "Spain" app.factory 'personService', () -> { getById: Person.getById 

}



<참조>

  - 원문 : Understanding Service Types

  - 가장 잘 설명된 글 : http://stackoverflow.com/questions/15666048/angular-js-service-vs-provider-vs-factory (강추)

  - 관련글 : GDG Korea WebTech 고재도님 링크

  - AngularJS Creating Service 매뉴얼

  - 이미지 : AngularJS Large Scale Architecture

  - JavaScript에서 객체를 만드는 3가지 방법

  - $provider를 통한 생성

저작자 표시 비영리 변경 금지
신고
posted by peter yun 윤영식
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