AngularJS 개발자 가장 자주 저지른 10개 오류

AngularJS 현재 가장 활발한 자바스크립트 프레임 하나이다, AngularJS 목표 중의 작은 개발 프로세스, 이 일은 AngularJS 아주 잘 빌드 소형 app 원형, 하지만 AngularJS 대해 모든 기능을 클라이언트 응용 프로그램 같은 강대하다, 그것은 결합 개발 간편하다, 널리, 뛰어난 성능 특성, 으로 널리 사용. 그러나 많은 사용 도 에 수많은 잘못된 영역. 이하 이 목록 최신 거야 흔히 볼 수 있는 일부 AngularJS 잘못된 사용, 특히 app 개발 과정에서.

1. MVC 디렉터리 구조

AngularJS, 直白地说, 就是一个MVC框架. 它的模型并没有像backbone.js框架那样定义的如此明确, 但它的体系结构却恰如其分. 当你工作于一个MVC框架时, 普遍的做法是根据文件类型对其进行归类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
templates/
    _login.html
    _feed.html
app/
    app.js
    controllers/
        LoginController.js
        FeedController.js
    directives/
        FeedEntryDirective.js
    services/
        LoginService.js
        FeedService.js
    filters/
        CapatalizeFilter.js

보아하니 이 마치 한 분명히 구조, 하물며 Rails 역시 이렇게 하는. 그러나 일단 app 규모가 시작 확장 이런 구조는 야기할 네가 한 번 더 많은 디렉터리 열기 간에 너는 사용 sublime, Visual Studio 또는 Vim 결합 Nerd Tree, 너 다 투입 많은 시간을 디렉터리 나무 중 끊임없이 地滑 위에서 미끄러져 내리다.

과 파일 형식 규정 따라 다릅니다. 대신 우리는 따라 나누다 수 있습니다. 파일 특성:

1
2
3
4
5
6
7
8
9
10
11
12
13
app/
    app.js
    Feed/
        _feed.html
        FeedController.js
        FeedEntryDirective.js
        FeedService.js
    Login/
        _login.html
        LoginController.js
        LoginService.js
    Shared/
        CapatalizeFilter.js

이런 디렉터리 구조 우리가 더 쉽게 찾을 수 있는 어떤 특성 과 관련된 모든 파일 뒤이어 속도를 우리 개발 진행.비록.html 것이다,.js 파일 아주 한 군데 쟁의 존재할 수 있지만, 에너지 절약 시간 더 가치.

2. 모듈

모든 걸 다 다 놓고 주 모듈 다음 매우 흔히 볼 수 있는 것에 대해, 소형 app, 처음에는 결코 아무 문제, 그러나 너는 곧 발견 구덩이 아버지 일 왔다.

1
2
3
4
5
6
7
var app = angular.module('app',[]);
app.service('MyService', function(){
    //service code
});
app.controller('MyCtrl', function($scope, MyService){
    //controller code
});

그 후에 한 흔한 정책 같은 유형의 대상에 대한 분류.

1
2
3
4
5
6
7
8
9
10
11
var services = angular.module('services',[]);
services.service('MyService', function(){
    //service code
});
var controllers = angular.module('controllers',['services']);
controllers.controller('MyCtrl', function($scope, MyService){
    //controller code
});
var app = angular.module('app',['controllers', 'services']);

이런 방식 과 앞에서 첫 부분 에 논급한 디렉터리 구조 거의: 부족하다.같은 이념 따라 수 특성 분류 따라 이 가져오겠습니다 확장 성.

1
2
3
4
5
6
7
8
var sharedServicesModule = angular.module('sharedServices',[]);
sharedServices.service('NetworkService', function($http){});
var loginModule = angular.module('login',['sharedServices']);
loginModule.service('loginService', function(NetworkService){});
loginModule.controller('loginCtrl', function($scope, loginService){});
var app = angular.module('app', ['sharedServices', 'login']);

우리가 개발 한 대형 프로그램 때 아마 결코 모든 게 다 포함 한 페이지에.같은 류 특성 처하게 될 한 모듈 안에 할 수 있 도록 크로스 app 간 중용하다 모듈 더 쉽다.

3. 의존 주입

의존 주입 것은 AngularJS 최고의 모드 중 그것 때문에 테스트 더욱 간단하다 고 의존 어떤 지정한 대상 모두 매우 명확하다.AngularJS 있는 주입 방식은 매우 가장 간단한 방법 만 필요 될 의존 이름 전래 모듈 function 중에 있습니다.:

1
2
3
4
5
6
7
var app = angular.module('app',[]);
app.controller('MainCtrl', function($scope, $timeout){
    $timeout(function(){
        console.log($scope);
    }, 1000);
});

이곳은 매우 뚜렷하다. MainCtrl 의존 $scope 및$timeout.

너 그 배치 될 때까지 준비 다 생산 환경 결코 희망을 간소화하다 코드 때 모두 매우 아름답다.만약 사용 UglifyJS, 전에 예를 아래에 이렇게 될 줄:

1
2
var app=angular.module("app",[]);
app.controller("MainCtrl",function(e,t){t(function(){console.log(e)},1e3)})

지금 AngularJS 어떻게 알아 MainCtrl 의존 누가? AngularJS 제공 일종의 아주 간단한 해결책, 곧 의존 으로서 배열 전래, 배열 마지막 한 요소 는 함수 모든 의존 항목 로서 그 매개 변수.

1
2
3
4
5
app.controller('MainCtrl', ['$scope', '$timeout', function($scope, $timeout){
    $timeout(function(){
        console.log($scope);
    }, 1000);
}]);

이렇게 하면 간소화하다 코드 수 있으며, AngularJS 어떻게 이런 명확하게 설명을 의존:

1
app.controller("MainCtrl",["$scope","$timeout",function(e,t){t(function(){console.log(e)},1e3)}])

3.1 전역 의존

이 편찬한 AngularJS 프로그램 나타날 때 항상 이런 상황: 어느 대상으로 한 의존 이 대상이 될 것이며, 또 그 자신의 바인딩 은 전역 scope 위에 이 의미한다 어떤 AngularJS 코드 중 이 의존 다 사용할 수 없습니다. 그러나 이 오히려 깨진 의존 주입 모델 을 초래 일부 문제를 특히 구현되었다 테스트 과정에서.

사용할 수 없는 것이다 AngularJS 쉽게 이 모듈에서 전역 의존 패키지 들어갈 수 AngularJS, 그래서 그들은 같은 표준 모듈 그렇게 의해 주입 들어가다.

Underscrore.js한 매우 칭찬하다 있는 라이브러리, 그것은 대체해 함수식 스타일 슬림 자바스크립트 코드, 아래와 같은 방식으로 너 가 그 전화한다 한 모듈:

1
2
3
4
5
6
7
8
9
10
11
12
13
var underscore = angular.module('underscore', []);
underscore.factory('_', function() {
  return window._; //Underscore must already be loaded on the page
});
var app = angular.module('app', ['underscore']);
app.controller('MainCtrl', ['$scope', '_', function($scope, _) {
    init = function() {
          _.keys($scope);
      }
      init();
}]);

이런 방법은 허용 으로 응용 프로그램 계속 AngularJS 의존 주입 스타일 을 개발 동시에 지금 테스트 단계 될 수 있 underscore 교환 나가.

이것은 아마도 보기에 매우 자질구레하다, 뭐 필요한 있지만, 만약 당신 코드 중에 지금 사용 use strict. (또한 반드시 사용) 이 바로 그 필요한 거야.

4. 컨트롤러 팽창

제어기, AngularJS 고기, 감자, 자칫 조심하지 않으면 곧 너무 많이 논리 가입 그중 특히 막 시작했을 때,.컨트롤러 영원히 가야 조작 DOM 또는 소지하고 DOM 선택기. 그것은 우리가 필요한 명령, ng-model 사용하는 데.같은 것, 비즈니스 논리 존재 서비스 중 꼭 컨트롤러.

데이터 역시 반드시 저장소 서비스 중 오직 그것들은 이미 묶여있습니다 지금 $scope 위에. 서비스 자체에 한 예, 응용 프로그램의 전체 생명 주기 다 존재, 그러나 컨트롤러 응용 프로그램 각 상태 사이 과도. 만약 데이터 보존되어 있다 컨트롤러 중 때 그 때 다시 实例化 필요하다고 다시 에서 데이터를 가져오는 것이다. 설령 데이터는 저장된 localStorage 에서 검색 속도도 더 자바스크립트 변수 천천히 한 자릿수.

AngularJS은 하나의 원칙을 따라야 직책을 (SRP) 때 실행 양호하다. 만약 컨트롤러, 보기 및 모델 간 코디네이터, 그럼 그것은 포함된 논리 마땅히 되도록 적게 이 같은 줄 테스트 에 편리하다.

5. Service vs Factory

거의 매주 한 AngularJS 개발자 지금 처음 배울 때 악착같으니, 이 명사는 에 시달 이 정말 너무 반드시 그것들은 바로 거의 같은 사물에 대한 문법 사탕 것 때문에!

다음은 지금 AngularJS 소스 코드 중 정의:

1
2
3
4
5
6
7
8
9
function factory(name, factoryFn) {
    return provider(name, { $get: factoryFn });
}
function service(name, constructor) {
    return factory(name, ['$injector', function($injector) {
      return $injector.instantiate(constructor);
    }]);
}

이 플러그인은 원본 코드에서 너 볼 수 있을 거야 factory, service 단지 호출 함수, 때문에 후자 또 호출 거야 provider 함수.사실 나도 좀 AngularJS 위해 값, 상수 및 장식 제공 추가 provider 패키지, 그러나 이 결코 비슷한 곤혹 때문에, 그들은 문서 모두 매우 뚜렷하다.

때문에 service 단지 호출 거야 factory 함수, 이 무슨 차이가 있나요? 단서가 있다$injector.instantiate: 지금这个函数中, $injector在service的构造函数中创建了一个新的实例.

다음은 예를 하나 전시 하나 service, 한 factory 어떻게 같은 일을 완성하다.:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var app = angular.module('app',[]);
app.service('helloWorldService', function(){
    this.hello = function() {
        return "Hello World";
    };
});
app.factory('helloWorldFactory', function(){
    return {
        hello: function() {
            return "Hello World";
        }
    }
});

이 helloWorldService 또는 helloWorldFactory 의해 주입 까지 컨트롤러 중, 그것들은 모두 한 hello 방법이 있어, 복귀"hello world". service 의 생성자 성명 때 实例化 의해 한 번 동시에 factory 대상, 매 번 의해 주입 때 배달 있지만 여전히 하나만 factory 인스턴스. 모든 providers 다 싱글 사례.

이왕이면 같은 일을 할 수 있는 두 가지 다른 풍격을 왜 필요해? 상대적 으로 service, factory 에 더 많은 융통성이 있다. 왜냐하면 그것은 반환 함수, 이 함수 후 의해 새 나올 수 있다.이 대상 지향 프로그래밍 중 정해서 된 공장 모드 개념, 공장 하나 만들 수 있는 다른 대상 대상.

1
2
3
4
5
6
7
8
9
app.factory('helloFactory', function() {
    return function(name) {
        this.name = name;
        this.hello = function() {
            return "Hello " + this.name;
        };
    };
});

여기 한 컨트롤러 예제 사용하여 service, 두 factory, helloFactory 복귀 한 함수, 이 새 대상 때 설정name 값.

1
2
3
4
5
6
7
8
9
app.controller('helloCtrl', function($scope, helloWorldService, helloWorldFactory, helloFactory) {
    init = function() {
      helloWorldService.hello(); //'Hello World'
      helloWorldFactory.hello(); //'Hello World'
      new helloFactory('Readers').hello() //'Hello Readers'
    }
    init();
});

여기 처음 배울 때, 가장 좋은 것은 단지 사용 service.

Factory디자인 포함하고 많은 사유 방법의 类时 또한 매우 유용하다:

1
2
3
4
5
6
7
8
9
10
11
app.factory('privateFactory', function(){
    var privateFunc = function(name) {
        return name.split("").reverse().join(""); //reverses the name
    };
    return {
        hello: function(name){
          return "Hello " + privateFunc(name);
        }
    };
});

이 예를 통해 우리는 수 있도록 privateFactory 의 공유 API 접근할 수 없습니다 privateFunc 방법을 다 이런 모델 은 service 중 할 수 있지만 factory 중 더 쉽다.

6. 사용할 수 없다.Batarang

Batarang한 데 뛰어난 크롬 플러그인, 개발 및 테스트 AngularJS app.

Batarang에 탐색 모델 능력 이 때문에 우리 능력 관찰 AngularJS 내부 어떻게 확정 바인딩 까지 범위 위의 모델, 이 처리 명령 및 격리 일정한 범위 관찰 바인딩 값 때 매우 유용하다.

Batarang나도 하나를 제공하였다 의존하는 그래프, 우리가 지금 접촉 한 bmc 테스트 코드 라이브러리 이 의존하는 그래프 있으면 유용합니다. 그것은 결정할 수 있는 어떤 서비스를 중점적으로 의해 잘 한다.

결국 Batarang 제공 성능 분석. 할 수 없다 Angular 가방 바로 쓸 성능, 그러나 대해 한 가득 사용자 정의 명령, 콤플렉스 로직 응용 경우 때로는 그냥 그렇게 유창하다. Batarang 성능 도구를 사용할 수 있게 직접 관찰할 한 digest 주기 함수 실행 중 어느 것이 가장 긴 시간. 성능 도구 있어도 전체 watch 나무 한 그루가 전시, 우리 많이 가지고 watcher 때 이 매우 유용하다.

7. 과다watcher

지난 한 점 에서 우리 얘기를 할 수 없다, AngularJS 가방 바로 쓸 성능이 양호하다. 에 필요 한 digest 기간 중 완료 더러운 데이터 검사, 일단 watcher 수가 성장이 약 2000 때 이 주기 바로 생기는 현저한 성능 문제. (2000 이 숫자는 말하면 반드시 인한 성능 대폭 하락하였다. 그러나 이것은 좋은 경험을 수치. 在AngularJS 1.3 release버전 중 이미 일부 엄격히 통제할 수 digest 주기 변경, Aaron Gray 좋은 글 한 편을 이에 대한 설명. )

이하 이 '즉시 실행 함수 표현식 (IIFE) "인쇄 무슨 현재 페이지에 모든 watcher 개수 너 간단히 자기들의 붙여넣을 콘솔 중 관찰 결과.이 단락의 IIFE 생활에서 Jared 지금 StackOverflow 위의 대답하다:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
(function () {
    var root = $(document.getElementsByTagName('body'));
    var watchers = [];
    var f = function (element) {
        if (element.data().hasOwnProperty('$scope')) {
            angular.forEach(element.data().$scope.$$watchers, function (watcher) {
                watchers.push(watcher);
            });
        }
        angular.forEach(element.children(), function (childElement) {
            f($(childElement));
        });
    };
    f(root);
    console.log(watchers.length);
})();

이 방법을 통해 얻을 수 있는 watcher 결합 Batarang 성능 분야 중 watch 나무 볼 수 있는 거 어디 반복 코드 또는 있다 어디가 존재 변하지 데이터 동시에 갖 watch.

이 존재 변하지 데이터, 넌 또 쓰려고 AngularJS 자기들의 스텐실 녹는다, 사용 bindonce 고려할 수 있습니다.Bindonce 한 간단한 명령, 마음대로 AngularJS 중 스텐실 사용, 하지만 그것은 결코 안 가입 watch, 곧 보장 watch 수가 없을 것이다.

8. $scope 범위를 한정하다.

Javascript기반 원형 상속 및 대상 지향 중 클래스 상속 기반 미묘한 차이 있다, 이 보통 뭐 문제가 있지만 이 미묘한 의 사용할 때 표현 나온 것이다 $scope 있다. 지금 AngularJS 중에 모든 $scope 다 상속 아버지 $scope 최고 층 윤작이라고$rootScope. ($scope 전통적 명령 약간 다르다. 그것들은 반드시 역할 범위 i 있을 뿐만 아니라 단지 명시적 성명을 상속 속성. )

원형 상속 특성 때문에 지금 아버지 종류 및 하위 클래스 간 공유 데이터 그다지 중요하지 않다. 그러나 만약 조심하지 않으면 도 쉽게 오용 한 부 $scope 속성.

예를 들면, 우리는 필요 한 탐색 표시줄 이전 사용자 이름 표시, 이 사용자 이름 은 등록 양식 중 입력, 아래 이런 시도는 아마 할 수 있는 일:

1
2
3
4
5
6
7
<div ng-controller="navCtrl">
   <span>{{user}}</span>
   <div ng-controller="loginCtrl">
        <span>{{user}}</span>
        <input ng-model="user"></input>
   </div>
</div>

그럼 문제 와 … …: text input 중 설치 user 있는 ng-model, 사용자는 입력 내용 때 그 때 어느 스텐실 당할 업데이트? navCtrl 아니면 loginCtrl, 아니면 다?

만약 네가 선택한 loginCtrl, 그럼 아마 이미 이해하는 원형 상속 어떻게 일을 했다.

당신이 검색 단어 액면가 때 원형 체인 결코 역할을 하다.만약 navCtrl 것도 동시에 의해 업데이트 말을 검색 원형 체인 반드시 하지만 만약 값 한 사람 이 바로.(기억, 자바스크립트 중 함수, 배열 과 대상 다 대상)

그러니까 예상 행위는 얻게 필요 는 navCtrl 에서 만드십시오. 대상, 그것은 수 loginCtrl 의해 임용하다.

1
2
3
4
5
6
7
<div ng-controller="navCtrl">
   <span>{{user.name}}</span>
   <div ng-controller="loginCtrl">
        <span>{{user.name}}</span>
        <input ng-model="user.name"></input>
   </div>
</div>

지금 에 user 한 대상, 원형 체인 곧 작용하다, navCtrl 스텐실, $scope 및 loginCtrl 악착같으니 업데이트.

이 보기에 한 매우 부자연스럽다. 예를 들어, 하지만 당신이 사용합니다. 일부 명령 만들게요 하위 $scope. 예 ngRepeat 때 이 문제는 쉽게 생기는 것이다.

9. 수동 테스트

TDD 아마 아니라 모든 개발자 다 좋아하는 개발 방식 때문에 따라서 개발자 검사 코드 지 여부를 작업 또는 영향을 다른 걸 때 수공 테스트 그들은.

테스트 AngularJS app 안 가, 이 도리가 없다.AngularJS 디자인 때문에 그것은 처음부터 끝까지 다 정말 테스트, 주사, ngMock 모듈 바로 명증 의존.AngularJS 핵심 팀 이미 많은 개발 할 수 있 도록 테스트 한단계 더 도구.

9.1 Protractor

단위 테스트 한 테스트 작업 기초 하지만 고려해 app 갈수록 복잡한 통합 테스트 더 밀착 실제 상황.다행히, AngularJS 핵심 팀 이미 제공 필요한 도구.

우리는 이미 건립 Protractor 한 단-대-단 있는 측정기 으로 아날로그 사용자 상호 이 너를 도울 수 있는 인증 너의 AngularJS 프로그램 상태.

Protractor사용 Jasmine 테스트 프레임워크 정의 테스트, Protractor 다른 페이지 교호 행위에 대해 매우 건장한 API 하나 있다.

우리 또 일부 다른 단-대-단 테스트 도구, 근데 Protractor 우세를 이해할 수 있는 것은 그것을 어떻게 및 AngularJS 코드 공동 작업, 특히 $digest 기간 중.

9.2 Karma

일단 우리 손으로 Protractor 완성되었다 통합 테스트 작성함 일을 이어서 바로 집행할 테스트.대기 테스트 실행, 특히 통합 테스트 모든 개발자 대해 모두 일종의 은은한 슬픈.AngularJS 핵심 팀 또한 매우 극히 계란 아프다, 그래서 그들은 개발 되었다 Karma.

Karma한 측정기, 그것은 도움이 닫기 되돌림 루프.Karma 할 수 있는 건 이, 왜냐하면 그것은 지정한 파일 의해 바뀔 때 그냥 시험 실행.Karma 동시에 도 여러 개의 브라우저 위에 시험 실행, 다른 장치 해도 가리키는 Karma 서버, 이렇게 하면 더 수정할 수 없이 진실한 세계 응용 장면.

10. 사용jQuery

jQuery한 酷炫 있는 라이브러리, 그것은 어떤 표준화 크로스 플랫폼 개발 거의 이미 되는 현대화 웹 개발 필수품.근데 비록 JQuery 이렇게 많은 우수 특성, 그것은 이념 과 AngularJS 일치하지 않아.

AngularJS한 데 건립 app 틀, 때문에 JQuery 은 한 간소화 'HTML 문서 작업, 이벤트 처리, 애니메이션, Ajax' 창고.이것은 두 가장 기본적인 차이, AngularJS 주력 프로그램 구조 와 상관없이 HTML 페이지.

더 나은 이해를 어떻게 하나 세우다 AngularJS 프로그램, 제발 그만 jQuery 사용. JQuery 개발자 으로 하여금 현존 HTML 표준 사고 문제가 있지만 문서 안에 말한 것 같다 "AngularJS 수 있도록 당신이 프로그램에서 확장 HTML 이 어휘".

DOM조작 만 명령 중 완성해야 한다. 그러나 이것은 결코 그들의 쓸 수 있다는 것을 의미한다 JQuery 패키지.너 JQuery 사용하기 전에 너는 반드시 항상 가서 생각해? AngularJS 이미 이 기능을 제공합니다.내가 기댈 수 있는 강력한 때 명령 서로 생성 도구, 이것은 확실히 매우 강대하다.

그러나 아주 좋은 JQuery 것은 필수품 때 이런 날이 올 줄 수도 있지만, 처음부터 그것을 위해, 한 흔히 볼 수 있는 오류.

결론

AngularJS한 탁월한 프레임, 커뮤니티 도움 아래 시종 진보하다.비록 AngularJS 여전히 한 발전 개념, 그러나 내가 원하는 사람들이 따라야 할 수 이상 논급한 이 약속 피할 수 AngularJS 응용 개발 에 만난 그 문제를.

글쓴이 정훈 작성일 2014-11-01 02:30