귀중한 많은 소스 덕분에 AngularJS 앱에서 구성 요소를 구현하기위한 일반적인 권장 사항이 있습니다.
제어 장치
컨트롤러는 모델과 뷰 사이의 중간 계층 이어야합니다 . 가능한 한 얇게 만드십시오 .
컨트롤러에서 비즈니스 로직 을 피하는 것이 좋습니다 . 모델로 이동해야합니다.
컨트롤러는 메소드 호출 (자식이 부모와 통신을 원할 때 가능) 또는 $ emit , $ broadcast 및 $ on 메소드를 사용하여 다른 컨트롤러와 통신 할 수 있습니다 . 전송 및 브로드 캐스트 된 메시지는 최소한으로 유지해야합니다.
컨트롤러는 프리젠 테이션 또는 DOM 조작을 신경 쓰지 않아야합니다 .
중첩 된 컨트롤러 를 피 하십시오 . 이 경우 상위 컨트롤러는 모델로 해석됩니다. 대신 공유 서비스로 모델을 주입하십시오.
컨트롤러의 범위 는 프리젠 테이션 모델 디자인 패턴 과 같이 뷰와 모델 을 바인딩 하고 뷰 모델 을
캡슐화 하는 데 사용해야합니다 .
범위
로 처리 범위 읽기 전용 템플릿에 와 쓰기 전용 가능한 컨트롤러 . 범위의 목적은 모델이 아니라 모델을 참조하는 것입니다.
양방향 바인딩 (ng-model)을 수행 할 때 범위 속성에 직접 바인딩하지 않아야합니다.
모델
AngularJS의 모델은 service에 의해 정의 된 싱글 톤 입니다.
모델은 데이터와 디스플레이를 분리하는 훌륭한 방법을 제공합니다.
모델은 일반적으로 정확히 하나의 종속성 (일부 형태의 이벤트 이미 터 형태, 일반적으로 $ rootScope )을 가지며 테스트 가능한 도메인 로직을 포함하므로 단위 테스트의 주요 후보입니다 .
모델은 특정 단위의 구현으로 간주되어야합니다. 단일 책임 원칙을 기반으로합니다. Unit은 실세계에서 단일 엔티티를 나타내고 데이터 및 상태의 관점에서 프로그래밍 세계에서 기술 할 수있는 관련 로직의 자체 범위를 담당하는 인스턴스입니다 .
모델은 애플리케이션의 데이터를 캡슐화
하고 해당 데이터에 액세스하고 조작 할 수있는 API 를 제공 해야합니다.
모델은 휴대 가 가능 하여 유사한 응용 분야로 쉽게 운반 할 수 있습니다.
모델에서 단위 로직을 분리하면보다 쉽게 찾고 업데이트하고 유지 관리 할 수 있습니다.
모델은 전체 응용 프로그램에 공통적 인보다 일반적인 글로벌 모델의 방법을 사용할 수 있습니다.
구성 요소 결합을 줄이고 단위 테스트 가능성 과 유용성을 높이는 데 의존하지 않는 경우 의존성 주입을 사용하여 모델에 다른 모델의 구성을 피하십시오 .
모델에서 이벤트 리스너를 사용하지 마십시오. 단일 책임 원칙 측면에서 테스트하기가 더 어렵고 일반적으로 모델을 종료합니다.
모델 구현
모델이 데이터 및 상태 측면에서 일부 논리를 캡슐화해야하므로 멤버에 대한 액세스를 구조적으로 제한해야하므로 느슨한 결합을 보장 할 수 있습니다.
AngularJS 애플리케이션에서이를 수행하는 방법은 팩토리 서비스 유형을 사용하여 정의하는 것 입니다. 이를 통해 개인 속성 및 메서드를 매우 쉽게 정의 할 수 있으며 공개적으로 액세스 가능한 항목을 한 곳에서 반환하여 개발자가 실제로 읽을 수 있습니다.
예 :
angular.module('search')
.factory( 'searchModel', ['searchResource', function (searchResource) {
var itemsPerPage = 10,
currentPage = 1,
totalPages = 0,
allLoaded = false,
searchQuery;
function init(params) {
itemsPerPage = params.itemsPerPage || itemsPerPage;
searchQuery = params.substring || searchQuery;
}
function findItems(page, queryParams) {
searchQuery = queryParams.substring || searchQuery;
return searchResource.fetch(searchQuery, page, itemsPerPage).then( function (results) {
totalPages = results.totalPages;
currentPage = results.currentPage;
allLoaded = totalPages <= currentPage;
return results.list
});
}
function findNext() {
return findItems(currentPage + 1);
}
function isAllLoaded() {
return allLoaded;
}
// return public model API
return {
/**
* @param {Object} params
*/
init: init,
/**
* @param {Number} page
* @param {Object} queryParams
* @return {Object} promise
*/
find: findItems,
/**
* @return {Boolean}
*/
allLoaded: isAllLoaded,
/**
* @return {Object} promise
*/
findNext: findNext
};
});
새 인스턴스 만들기
의존성 주입을 중단하기 시작하고 라이브러리가 특히 제 3 자에게 어색하게 작동하므로 새로운 기능을 반환하는 팩토리를 사용하지 마십시오.
동일한 작업을 수행하는 더 좋은 방법은 팩토리를 API로 사용하여 getter 및 setter 메소드가 첨부 된 오브젝트 콜렉션을 리턴하는 것입니다.
angular.module('car')
.factory( 'carModel', ['carResource', function (carResource) {
function Car(data) {
angular.extend(this, data);
}
Car.prototype = {
save: function () {
// TODO: strip irrelevant fields
var carData = //...
return carResource.save(carData);
}
};
function getCarById ( id ) {
return carResource.getById(id).then(function (data) {
return new Car(data);
});
}
// the public API
return {
// ...
findById: getCarById
// ...
};
});
글로벌 모델
일반적으로 이러한 상황을 피하고 모델을 올바르게 설계하여 컨트롤러에 주입하여보기에 사용할 수 있도록하십시오.
특히 일부 방법은 응용 프로그램 내에서 전역 접근성을 필요로합니다. 이를 가능하게하기 위해 $ rootScope 에서 ' common '속성을 정의 하고 애플리케이션 부트 스트랩 동안 commonModel에 바인딩 할 수 있습니다 .
angular.module('app', ['app.common'])
.config(...)
.run(['$rootScope', 'commonModel', function ($rootScope, commonModel) {
$rootScope.common = 'commonModel';
}]);
모든 글로벌 메소드는 ' 공통 '속성 내에 있습니다. 이것은 일종의 네임 스페이스 입니다.
그러나 $ rootScope에 직접 메소드를 정의하지 마십시오 . 이로 인해 뷰 범위 내에서 ngModel 지시문과 함께 사용 하면 예기치 않은 동작 이 발생할 수 있으며 일반적으로 범위가 흩어지고 범위 메서드가 문제를 재정의합니다.
자원
리소스를 사용하면 다른 데이터 소스 와 상호 작용할 수 있습니다 .
single-responsibility-principle을 사용하여 구현해야합니다 .
특히 HTTP / JSON 엔드 포인트에 재사용 가능한 프록시입니다.
모델에 리소스가 주입되어 데이터를 전송 / 검색 할 수 있습니다.
자원 구현
RESTful 서버 측 데이터 소스와 상호 작용할 수있는 자원 오브젝트를 작성하는 팩토리입니다.
리턴 된 자원 오브젝트에는 하위 레벨 $ http 서비스와 상호 작용할 필요없이 상위 레벨 작동을 제공하는 조치 메소드가 있습니다.
서비스
모델과 리소스는 모두 서비스 입니다.
서비스는 독립적 이며 느슨하게 결합 된 독립적 인 기능 단위입니다.
서비스는 Angular가 서버 측에서 클라이언트 측 웹 앱으로 가져 오는 기능으로, 오랫동안 서비스가 일반적으로 사용되었습니다.
Angular 앱의 서비스는 의존성 주입을 사용하여 서로 연결된 대체 가능한 객체입니다.
Angular는 다양한 유형의 서비스와 함께 제공됩니다. 각각 자체 사용 사례가 있습니다. 자세한 내용은 서비스 유형 이해를 읽으십시오 .
애플리케이션에서 서비스 아키텍처의 기본 원칙 을 고려 하십시오.
일반적으로 웹 서비스 용어 에 따르면 :
서비스는 제공자 엔티티 및 요청자 엔티티의 관점에서 일관된 기능을 형성하는 태스크를 수행하는 기능을 나타내는 추상 자원입니다. 사용하려면 구체적인 제공자 에이전트가 서비스를 실현해야합니다.
클라이언트 측 구조
일반적으로 응용 프로그램의 클라이언트 쪽은 모듈 로 분할됩니다 . 각 모듈은 하나의 단위 로 테스트 할 수 있어야합니다 .
유형이 아닌 기능 / 뷰 또는 기능 에 따라 모듈을 정의하십시오 . 자세한 내용은 Misko의 프레젠테이션 을 참조하십시오.
모듈 구성 요소는 일반적으로 컨트롤러, 모델, 뷰, 필터, 지시문 등과 같은 유형별로 그룹화 될 수 있습니다.
그러나 모듈 자체는 재사용 가능 하고 전송 가능 하며 테스트 가능 합니다.
개발자가 코드의 일부와 모든 종속 항목을 찾는 것이 훨씬 쉽습니다.
자세한 내용 은 Large AngularJS 및 JavaScript 응용 프로그램의 코드 구성을 참조 하십시오.
폴더 구조의 예 :
|-- src/
| |-- app/
| | |-- app.js
| | |-- home/
| | | |-- home.js
| | | |-- homeCtrl.js
| | | |-- home.spec.js
| | | |-- home.tpl.html
| | | |-- home.less
| | |-- user/
| | | |-- user.js
| | | |-- userCtrl.js
| | | |-- userModel.js
| | | |-- userResource.js
| | | |-- user.spec.js
| | | |-- user.tpl.html
| | | |-- user.less
| | | |-- create/
| | | | |-- create.js
| | | | |-- createCtrl.js
| | | | |-- create.tpl.html
| |-- common/
| | |-- authentication/
| | | |-- authentication.js
| | | |-- authenticationModel.js
| | | |-- authenticationService.js
| |-- assets/
| | |-- images/
| | | |-- logo.png
| | | |-- user/
| | | | |-- user-icon.png
| | | | |-- user-default-avatar.png
| |-- index.html
각도 응용 프로그램 구조화의 좋은 예는 angular -app에 의해 구현됩니다 -https : //github.com/angular-app/angular-app/tree/master/client/src
이것은 현대 응용 프로그램 생성기에서도 고려됩니다-https: //github.com/yeoman/generator-angular/issues/109