별도의 AngularJS 컨트롤러 파일을 만드는 방법은 무엇입니까?


315

모든 AngularJS 컨트롤러가 하나의 파일 controllers.js에 있습니다. 이 파일은 다음과 같이 구성됩니다.

angular.module('myApp.controllers', [])
  .controller('Ctrl1', ['$scope', '$http', function($scope, $http) {    
  }])
  .controller('Ctrl2', ['$scope', '$http', function($scope, $http) }
  }])

내가하고 싶은 것은 Ctrl1과 Ctrl2를 별도의 파일에 넣는 것입니다. 그런 다음 index.html에 두 파일을 모두 포함 시키지만 어떻게 구성해야합니까? 나는 이와 같은 일을 시도했지만 웹 브라우저 콘솔에서 컨트롤러를 찾을 수 없다는 오류가 발생합니다. 힌트가 있습니까?

StackOverflow를 검색하고 비슷한 질문을 찾았지만이 구문은 Angular 위에 다른 프레임 워크 (CoffeeScript)를 사용하므로 따라갈 수 없었습니다.


AngularJS : 여러 파일로 컨트롤러를 만드는 방법

답변:


399

파일 하나 :

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

두 번째 파일 :

angular.module('myApp.controllers').controller('Ctrl1', ['$scope', '$http', function($scope, $http){

}]);

파일 3 :

angular.module('myApp.controllers').controller('Ctrl2', ['$scope', '$http', function($scope, $http){

}]);

그 순서대로 포함하십시오. 모듈 선언 자체가 가능하도록 3 개의 파일을 권장합니다.


폴더 구조에 관해서는 주제에 대한 많은 의견이 있지만이 두 가지는 꽤 좋습니다.

https://github.com/angular/angular-seed

http://briantford.com/blog/huuuuuge-angular-apps.html


1
OP가 CoffeeScript 구문에 대해 혼동을 나타내는 경우 답변에 사용하지 않는 것이 가장 좋습니다.
Andrew

3
@Andrew imho 미래의 도움과 솔루션의 기록은 SO와 관련된 모든 것입니다.
Fresheyeball

2
@RuslanIsmagilov 당신 appCtrl은 글로벌 window.appCtrl입니다. 좋은 습관이 아닙니다.
Fresheyeball

1
@Fresheyeball,이 접근법의 문제점은 index.html에서 가져 오기 순서가 중요하다는 것입니다. 그렇지 않으면 Angular에서 오류가 발생합니다.
Deoxyseia

2
@hendryau, OP에있는 모듈 이름으로 작업하고있었습니다. 즉, 일부는 중앙 앱 모듈이 아닌 여러 이름 공간 모듈을 갖는 것이 조직적으로 더 좋다고 생각합니다.
Fresheyeball

177

끝에 배열과 함께 angular.module API 사용하면 angular에 새 모듈을 만들도록 지시합니다.

myApp.js

// It is like saying "create a new module"
angular.module('myApp.controllers', []); // Notice the empty array at the end here

배열없이 그것을 사용하는 것은 실제로 게터 함수입니다. 따라서 컨트롤러를 분리하려면 다음을 수행하십시오.

Ctrl1.js

// It is just like saying "get this module and create a controller"
angular.module('myApp.controllers').controller('Ctrlr1', ['$scope', '$http', function($scope, $http) {}]);

Ctrl2.js

angular.module('myApp.controllers').controller('Ctrlr2', ['$scope', '$http', function($scope, $http) {}]);

자바 스크립트를 가져 오는 동안 myApp.js 가 AngularJS 이후이지만 컨트롤러 / 서비스 / 등 앞에 있어야합니다. 그렇지 않으면 angular는 컨트롤러를 초기화 할 수 없습니다.


내 의존성을 어디에 써야합니까? var myapp = angular.module ( 'demo', [ 'ngRoute', 'ngCookies', 'ui.bootstrap', 'nvd3ChartDirectives', 'ui-rangeSlider', 'textAngular', 'angularTreeview']);
vipin

@vipin은 입력 한 것과 비슷하지만 컨트롤러, 서비스 등 위에 있는지 확인하십시오. 기술적으로 var myapp = ...; 각도는 당신을 위해 그것을 저장하기 때문에.
Jimmy Au

@JimmyAu 페이지에서 사용할 수 있도록 Ctrl1.js와 Ctrl2.js는 어디에로드됩니까? 각도 직후에 myApp.js를로드했지만 페이지에서 컨트롤러를 찾을 수 없습니다. 필요한 뷰에서 스크립트로 명시 적으로 추가해야합니까? 아니면 여전히 모든 페이지에 모든 컨트롤러 파일을 포함시켜야합니까?
Sinaesthetic

2
첫 번째 통화에만 []이 (가) 필요한 이유를 설명해 주셔서 감사합니다.
Jim B.

49

두 답변 모두 기술적으로 정확하지만이 답변에 다른 구문 선택을 도입하고 싶습니다. 이 imho는 주입으로 무슨 일이 일어나고 있는지를 더 쉽게 읽을 수있게 해줍니다.

파일 하나

// Create the module that deals with controllers
angular.module('myApp.controllers', []);

파일 2

// Here we get the module we created in file one
angular.module('myApp.controllers')

// We are adding a function called Ctrl1
// to the module we got in the line above
.controller('Ctrl1', Ctrl1);

// Inject my dependencies
Ctrl1.$inject = ['$scope', '$http'];

// Now create our controller function with all necessary logic
function Ctrl1($scope, $http) {
  // Logic here
}

파일 3

// Here we get the module we created in file one
angular.module('myApp.controllers')

// We are adding a function called Ctrl2
// to the module we got in the line above
.controller('Ctrl2', Ctrl2);

// Inject my dependencies
Ctrl2.$inject = ['$scope', '$http'];

// Now create our controller function with all necessary logic
function Ctrl2($scope, $http) {
  // Logic here
}

흥미롭게도 컨트롤러를 등록하기 위해 여러 파일로 갈 수 없습니다.
mrwaim

4
이런 코딩이 많이 보입니다. 장점은 무엇입니까? $ inject와 함수가 분리되어 있습니다.
Alaksandar Jesus Gene

2
코드를 읽기가 더 쉽다고 생각합니다. 정확히 무엇을 주입하고 있는지 알고 있습니다. 이것을 줄 단위로 "문제 분리"로 생각하십시오.
jason328 5

2
이와 같은 코드는 더 읽기 쉬운 코드를 생성 할뿐 아니라 디버그하기가 훨씬 쉽고 중첩 된 콜백 코드의 양을 줄입니다 ( github.com/johnpapa/angular-styleguide/blob/master/a1/… 참조 )
rfornal

이 1000 번 +1 할 수 있다면-브라보!
댄 체이스

17

이 솔루션은 어떻습니까? 파일의 모듈 및 컨트롤러 (페이지 끝) 여러 컨트롤러, 지시문 등에서 작동합니다.

app.js

var app = angular.module("myApp", ['deps']);

myCtrl.js

app.controller("myCtrl", function($scope) { ..});

html

<script src="app.js"></script>
<script src="myCtrl.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">

Google은 또한 상황에 따라 그룹화하는 Angular App Structure에 대한 모범 사례 권장 사항을 보유하고 있습니다 . 하나의 폴더에있는 모든 HTML이 아니라 로그인을위한 모든 파일 (html, css, app.js, controller.js 등). 따라서 모듈에서 작업하면 모든 지시문을 쉽게 찾을 수 있습니다.


3

간결성을 위해 다음은 전역 변수에 의존하지 않는 ES2015 샘플입니다.

// controllers/example-controller.js

export const ExampleControllerName = "ExampleController"
export const ExampleController = ($scope) => {
  // something... 
}

// controllers/another-controller.js

export const AnotherControllerName = "AnotherController"
export const AnotherController = ($scope) => {
  // functionality... 
}

// app.js

import angular from "angular";

import {
  ExampleControllerName,
  ExampleController
} = "./controllers/example-controller";

import {
  AnotherControllerName,
  AnotherController
} = "./controllers/another-controller";

angular.module("myApp", [/* deps */])
  .controller(ExampleControllerName, ExampleController)
  .controller(AnotherControllerName, AnotherController)

1
명명 된 함수를 사용하면 타이핑을 상당히 줄일 수 있습니다. 편리한 속성을 가지고 있습니다 name. 그래서 ExampleCtrl.name중복 대신에 간단하게 사용할 수 있습니다 .
Antti Pihlaja

0

그렇게 우아하지는 않지만 전역 변수를 사용하는 구현 솔루션에서 매우 간단합니다.

"첫 번째"파일에서 :


window.myApp = angular.module("myApp", [])
....

"second", "third"등에서


myApp.controller('MyController', function($scope) {
    .... 
    }); 

이 코드를 사용하지만 여전히 컨트롤러를로드 할 수 없습니까? 오류 발생 : 오류 : [ng : areq] 인수 'ProductCtrl'이 (가) 함수가 아니며 정의되지 않았습니다.
QViet

7
이것은 정말 나쁜 습관입니다
Brendan

@Kim Jong Un 생성 한 모듈에 컨트롤러를 추가 / 연결하지 않으면 해당 오류가 표시됩니다. 다음 구문을 사용하면 작동합니다.angular.module('myApp').controller('ProductCtrl', ['$scope', '$http', function($scope, $http){ //Your ProductCtrl code goes here }]);
Devner

1
@Brendan, 단순히 뭔가 나쁜 습관이라고 말하는 것이 아무것도 아닌 것보다 낫지 만 많지는 않습니다. 나쁜 습관이 다른 사람들 에게 도움이되는 이유를 알려주십시오 .
Mawg에 의하면 Monica Monica는
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.