AngularJS 시드 : JavaScript를 별도의 파일 (app.js, controllers.js, directives.js, filters.js, services.js)에 넣기


93

내 응용 프로그램을 구성하기 위해 angular-seed 템플릿을 사용하고 있습니다. 처음에는 모든 JavaScript 코드를 단일 파일 인 main.js. 이 파일에는 내 모듈 선언, 컨트롤러, 지시문, 필터 및 서비스가 포함되어 있습니다. 응용 프로그램은 이와 같이 잘 작동하지만 응용 프로그램이 더 복잡 해짐에 따라 확장 성과 유지 관리가 걱정됩니다. angular-seed 템플릿에 이들 각각에 대해 별도의 파일이 있음을 알았으므로 단일 main.js파일의 코드 를이 질문의 제목에 언급 된 다른 파일 각각 으로 배포하려고 시도 app/js했으며 angular 의 디렉토리 에서 찾았습니다. -씨앗 템플릿.

내 질문은 응용 프로그램이 작동하도록 종속성을 어떻게 관리합니까? 여기에 있는 기존 문서 는 주어진 각 예제가 단일 JavaScript 소스 파일을 보여주기 때문에 이와 관련하여 명확하지 않습니다.

내가 가진 것의 예는 다음과 같습니다.

app.js

angular.module('myApp', 
    ['myApp.filters',
     'myApp.services',
     'myApp.controllers']);

controllers.js

angular.module('myApp.controllers', []).
    controller('AppCtrl', [function ($scope, $http, $filter, MyService) {

        $scope.myService = MyService; // found in services.js

        // other functions...
    }
]);

filters.js

angular.module('myApp.filters', []).
    filter('myFilter', [function (MyService) {
        return function(value) {
            if (MyService.data) { // test to ensure service is loaded
                for (var i = 0; i < MyService.data.length; i++) {
                    // code to return appropriate value from MyService
                }
            }
        }
    }]
);

services.js

angular.module('myApp.services', []).
    factory('MyService', function($http) {
        var MyService = {};
        $http.get('resources/data.json').success(function(response) {
            MyService.data = response;
        });
        return MyService;
    }
);

main.js

/* This is the single file I want to separate into the others */
var myApp = angular.module('myApp'), []);

myApp.factory('MyService', function($http) {
    // same code as in services.js
}

myApp.filter('myFilter', function(MyService) {
    // same code as in filters.js
}

function AppCtrl ($scope, $http, $filter, MyService) {
    // same code as in app.js
}

종속성을 어떻게 관리합니까?

미리 감사드립니다.


2
이것에 대한 몇 가지 기사가 있습니다. 예를 들어, briantford.com/blog/huuuuuge-angular-apps.htmlyeoman 과 같은 일부 프로젝트. 이에 접근하는 방법에는 두 가지가 있습니다. 일부 기사에서 제안하는 것처럼 레이어 (각도 씨앗 등) 또는 기능별로 구성 요소를 분리하는 것입니다.
Eduard Gamonal 2013 년

예를 들어 angular.module ( 'myApp.service1', []) 모듈을 선언 할 때 [] 예를 들어 angular.module ( 'myApp.service1', [ 'myApp.service2', 'myApp) 에 종속성을 추가해야한다고 생각합니다. .service2 ']). . 저는 AngularJS를 처음 접했기 때문에 틀릴 수 있습니다. 이 문제가 해결되면 알려 주시면 답변을 게시하겠습니다.
Danny Varod

그 줄은 어디에 삽입해야합니까? angular.module('myApp.services', ['myApp.services']);운없이 app.js에 넣었 습니다.
ChrisDevo

@ChrisDevo 1. 댓글에 답글을 달 때 항상 '@'와 사용자 이름 (공백 없음)으로 댓글을 시작하면 사용자에게 알림이 전송됩니다. 2. myApp.services는 자체가 아닌 다른 모듈에 종속되어야합니다 (예 : angular.module('myApp.services', ['myApp.server', 'myApp.somethingElse']).
Danny Varod

@DannyVarod, 이전 댓글을 수정 했나요? angular.module('myApp.service1', ['myApp.service1', 'myApp.service2'])원래 대로 읽었습니다 . 그렇지 않으면 myApp.services를 자체 종속성으로 포함하지 않았을 것입니다.
ChrisDevo 2013 년

답변:


108

이 문제는 모든 개별 파일에서 응용 프로그램 모듈을 "재 선언"하기 때문에 발생합니다.

앱 모듈 선언 (선언이 올바른 용어인지 확실하지 않음)은 다음과 같습니다.

angular.module('myApp', []).controller( //...

애플리케이션 모듈에 대한 할당 (할당이 올바른 용어인지 확실하지 않음)은 다음과 같습니다.

angular.module('myApp').controller( //...

대괄호가 없음을 확인하십시오.

그래서, 이전 버전, 하나 대괄호 만 일반적으로 한 번 사용되어야한다 app.jsmain.js. 컨트롤러, 지시문, 필터 등 다른 모든 관련 파일 은 대괄호가 없는 후자의 버전을 사용해야합니다 .

그게 말이 되길 바랍니다. 건배!


9
이 문제에 대한 해결책을 찾았습니다. 하나의 모듈 만 필요한 것 같습니다 myApp. 내 app.js 파일에서 var를 만들었습니다. var myApp = angular.module('myApp', []);다른 모든 파일에서는 단순히이 var를 참조했습니다 (예 : myApp.filter('myFilter', function(MyService) { /* filter code */ });html의 스크립트 태그에 파일 이름을 추가하는 한 다른 선언 할 필요가 없었습니다. angular-seed 프로젝트 템플릿은 이와 관련하여 상당히 혼란 스럽습니다
ChrisDevo

1
이제 정말 혼란 스러워요. 내가 다시 사라 글로벌 VAR를 삭제 한 myApp지금의 익명 모듈 그래서, app.js: angular.module('myApp', ['myApp.filters', 'myApp.services', 'myApp.directives', 'myApp.controllers']);. 다른 모든 파일에서도 이와 같은 익명 모듈을 선언했습니다 angular.module('myApp.filter', []).filter('myFilter', function(MyService) { /* filter code */ });. 이제 내 앱도 이와 같이 작동합니다. 내 코드 기록을 살펴 봤는데 이것이 작동하지 않았을 때와 다른 점을 볼 수 없습니다.
ChrisDevo 2013 년

4
이 일을 약속합니다. Angular Apps를 개발하면서 매일 사용합니다. 다시 말하지만, angular.module('myApp', []);기본 js 파일에 (대괄호에주의) 선언이 하나 있습니다. 그런 다음 다른 모든 파일은 angular.module('myApp').controller또는 .directive구문 을 사용하여 모듈을 참조 합니다.
Justin L.

5
Angular가 myApp.controller, myApp.filters라는 모듈을 찾고 있기 때문에 오류가 발생합니다. 그러나 이들은 모듈이 아니며 myApp이라는 모듈을 확장하는 구성 요소입니다. 모듈 종속성에서 모든 myApp.what을 제거하면 모든 것이 작동합니다. 그냥 빈 대괄호를 유지 (당신이 다른 진정한 각도 모듈을 포함하지 않는 예를 들어 ngCookies, ngResource) 주요 응용 프로그램 모듈을 선언 할 때 :angular.module('myApp', []);
저스틴 L.

1
아, 그래. 이 때문에 앱 모듈에 대한 종속성과 같은 사람들을 배치함으로써, 오류가 발생하지 그들을 찾을 수 있습니다. 대괄호에서 꺼내면 마음대로로드 할 수 있으며 앱은 신경 쓰지 않습니다. ngResource확실히 모듈 선언 괄호에 넣는 것 중 하나입니다. 내 대답이 도움이 되었다면 투표하고 승인 해 주시면 감사하겠습니다.
Justin L.

12

응용 프로그램의 다른 부분 ( filters, services, controllers)을 다른 실제 파일에 저장하려면 다음 두 가지를 수행해야합니다.

  1. 더 나은 용어가없는 경우 해당 네임 스페이스를 귀하 app.js또는 각 파일에 선언 하십시오.
  2. 각 파일에서 해당 네임 스페이스를 참조하십시오.

따라서 app.js다음과 같이 보일 것입니다.

angular.module('myApp', ['external-dependency-1', 'myApp.services', 'myApp.controllers'])
.run(function() {
   //...

})
.config(function() {
  //...
});

그리고 각 개별 파일에서 :

services.js

angular.module('myApp.services', []); //instantiates
angular.module('myApp.services') //gets
.factory('MyService', function() { 
  return {};
});

controllers.js

angular.module('myApp.controllers', []); //instantiates
angular.module('myApp.controllers')      //gets
.controller('MyCtrl', function($scope) {
  //snip...
})
.controller('AccountCtrl', function($scope) {
  //snip...
});

이 모든 것을 하나의 호출로 결합 할 수 있습니다.

controllers.js
angular.module('myApp.controllers', []) 
.controller('MyCtrl', function($scope) {
 //snip...
});    

중요한 부분은 재정의해서는 안된다는 것입니다 angular.module('myApp'). 컨트롤러를 인스턴스화 할 때 덮어 쓰게 만들 수 있습니다.


1
이 접근 방식이 마음에 들어 계층 형 구조를 만드는 데 사용할 수 있습니다 (컨트롤러에 서비스 또는 필터가 필요함). 참고로, 컨트롤러에 대한 필터와 같은 하위 종속성이 주입되면 주입을 다시 선언하지 않고 위의 모든 부모 (트리로 시각화하는 경우)에서도 사용할 수 있습니다. 자녀를 바꾸고 부모에게 사용하는 경우에는 잊어 버리십시오. 또한 파일에 둘 이상의 모듈 (네임 스페이스)을 넣지 말고 여러 파일에서 동일한 네임 스페이스를 사용하지 않는 것이 좋습니다.
Gary

두 개의 컨트롤러 파일 또는 두 개의 서비스 파일이 있으면 어떻게합니까? 인스턴스화가 각 단일 파일에 대해 발생합니까?
Avinash 주권

3

myApp.services아직 정의하지 않았기 때문에 오류가 발생합니다 . 지금까지 내가 한 일은 모든 초기 정의를 하나의 파일에 넣은 다음 다른 파일에서 사용하는 것입니다. 예를 들어 다음과 같이 입력합니다.

app.js

angular.module('myApp.services', []);

angular.module('myApp', 
    ['myApp.services',
      ...]);

댓글 중 하나에서 언급 된 Eduard Gamonal 기사를 읽어야한다고 생각하지만 오류를 제거해야합니다 .


고마워요, Torsten,하지만 그 기사를 읽고 angular.module('myApp.services', []);내 app.js 파일에 줄 을 추가했습니다 . 둘 다 내 문제를 실제로 해결하지 못합니다.
ChrisDevo는
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.