단일 페이지 앱에서 AngularJS를 사용하는 여러 컨트롤러


102

단일 페이지 응용 프로그램에 여러 컨트롤러를 사용하는 방법을 알고 싶습니다. 나는 그것을 알아 내려고 노력했고 나와 매우 유사한 질문을 찾았지만 단일 페이지 앱에 여러 컨트롤러를 사용하지 않는 특정 문제를 해결하는 수많은 답변이 있습니다.

한 페이지에 여러 컨트롤러를 사용하는 것이 현명하지 않기 때문입니까? 아니면 가능하지 않습니까?

이미 메인 페이지에서 작동하는 멋진 이미지 캐 러셀 컨트롤러가 있지만 모달을 사용하는 방법 (예 : 모달)을 배우고이를위한 새 컨트롤러도 필요합니다 (또는 컨트롤러가 필요한 다른 것). 그러면 나는 무엇을 할 것인가?

나는 그들이 나와 거의 같은 것에 대해 묻는 다른 질문에 대한 몇 가지 대답을 보았습니다. 그리고 사람들은 "* OMG. 왜 그렇게 하시겠습니까, 그냥하세요 ..."라고 대답합니다.

가장 좋은 방법은 무엇이며 어떻게합니까?

편집하다

많은 사람들이 두 개의 컨트롤러를 선언 한 다음 ng-controller를 사용하여 호출하도록 응답하고 있습니다. 아래 코드를 사용하고 ng-controller로 MainCtrl을 호출합니다.

app.config(function($routeProvider, $locationProvider) {                        
  $routeProvider                                                                
       .when('/', {                                            
         templateUrl: "templates/main.html",                                               
         controller:'MainCtrl',                                
        })                                                                      
        .otherwise({                      
            template: 'does not exists'   
        });      
});

컨트롤러없이 ng-controller를 사용할 수 있는데 왜 여기에서 컨트롤러를 설정해야합니까? 이것이 나를 혼란스럽게하는 것입니다. (그리고 이런 식으로 두 개의 컨트롤러를 추가 할 수 없습니다.)


단일 .html 파일에 대해 2 개의 컨트롤러를 선언 할 수 있다고 생각하지 않습니다. 어떻게 된거 야? when: /home, controller: MainCtrl. 그 이상을 추가 할 수 없습니다. 아니면 그냥 ng-controller로 호출할까요?

3
@Mosho, 1 단계, 2 단계가 완료되었지만 방법이나 이유는 설명하지 마십시오. 그렇게 간단하다면 방법을 설명해주십시오. 그것은 AngularJS를 사용하는 것과 같습니다. 자세히 설명 할 수 있습니까? 아니면 6 월부터 답장하지 않을 수도 있습니다. 다른 사람이 설명 할 수 있습니까?
redfox05 2015

답변:


96

무엇이 문제입니까? 여러 컨트롤러를 사용하려면 여러 ngController 지시문을 사용하십시오.

<div class="widget" ng-controller="widgetController">
    <p>Stuff here</p>
</div>

<div class="menu" ng-controller="menuController">
    <p>Other stuff here</p>
</div>

평소처럼 응용 프로그램 모듈에서 컨트롤러를 사용할 수 있어야합니다.

이를 수행하는 가장 기본적인 방법은 다음과 같이 컨트롤러 기능을 선언하는 것만 큼 간단 할 수 있습니다.

function widgetController($scope) {
   // stuff here
}

function menuController($scope) {
   // stuff here
}

2
이것이 수행되는 방법입니까? 그 사용하여 임when /home, controller: MainCtrl

8
"ng-controller"옆에있는 각 DIV에 "ng-app"을 넣는 예제가 나오는 경우 "ng-app"하나만 "body"태그로 옮기고 div 당 " ng-app "태그) 첫 번째 컨트롤러 만 작동하는 경우. (나는 나의 각도 초보자 일에서 이것을 기억합니다.)
ftexperts

1
ng-controller여러 DOM 요소에서 사용 하면서 겪은 유일한 문제 는 .NET을 통해 DOM에 많은 항목이 인쇄되는 시나리오에서 말합니다 ng-repeat. 이들 각각이을 호출한다고 가정 해 보겠습니다 ng-controller="myController. 내 응용 프로그램에서 본 콘솔 로그 중 일부 myController에서이를 호출하는 DOM에서 렌더링되는 각 요소로 다시 초기화됩니다 .... 아마도 내 특정 사용에서 무언가를 망쳤거나 OP의 범위를 벗어난 것일 수 있습니다. 질문,하지만 호기심 다른 하나 전혀 .... 것을 경험 한 경우
twknab

91

"단일 페이지 앱"이라는 의미가 누락 된 것 같습니다.

이것은 물리적으로 하나의 .html을 갖게된다는 것을 의미하지 않고 대신 하나의 메인 index.html파일과 여러 개의 NESTED .html 파일을 갖게 됩니다. 그렇다면 왜 단일 페이지 앱일까요? 이렇게하면 표준 방식 (즉, 전체 페이지를 완전히 새로 고치는 브라우저 호출)으로 페이지를로드하지 않고 Angular / Ajax를 사용하여 콘텐츠 부분 만로드하기 때문입니다. 페이지 변경 사이에 깜박임이 보이지 않기 때문에 페이지에서 이동하지 않은 것 같은 인상을 받았습니다. 따라서 한 페이지에 머무르는 것처럼 느껴집니다.

이제 단일 페이지 앱 (예 : 집, 연락처, 포트폴리오 및 상점)에 대한 여러 콘텐츠를 원한다고 가정합니다. 단일 페이지 / 다중 콘텐츠 앱 (각도)은 다음과 같이 구성됩니다.

  • index.html: 머리글 <ng-view>및 바닥 글 포함
  • contacts.html: 연락처 양식 포함 (머리글 없음, 바닥 글 없음)
  • portfolio.html: 포트폴리오 데이터 포함 (머리글 없음, 바닥 글 없음)
  • store.html: 상점을 포함하고 머리글이없고 바닥 글이 없습니다.

색인에있는 상태에서 "연락처"라는 메뉴를 클릭하면 어떻게됩니까? Angular는 <ng-view>태그를 contacts.html코드로 대체합니다.

어떻게 달성합니까? 를 사용 ngRoute하면 다음과 같은 결과를 얻을 수 있습니다.

app.config(function($routeProvider, $locationProvider) {                        
  $routeProvider                                                                
       .when('/', {                                            
         templateUrl: "templates/index.html",                                               
         controller:'MainCtrl',                                
        })
        .when('/contacts', {                                            
         templateUrl: "templates/contacts.html",                                               
         controller:'ContactsCtrl',                                
        })                                                                 
        .otherwise({                      
            template: 'does not exists'   
        });      
});

이것은 올바른 컨트롤러를 전달하는 올바른 html을 호출합니다 (참고 : 경로를 사용하는 경우에 지시문을 지정하지 마십시오ng-controllercontacts.html ).

그런 다음, Contacts.html 페이지 내에서 ng-controller 지시문을 얼마든지 선언 할 수 있습니다. 그것들은 자식 컨트롤러가 될 것입니다 ContactCtrl(따라서 상 속됨). 그러나 단일 경로의 경우 routeProvider에서 "부분보기의 아버지 컨트롤러"역할을 할 단일 컨트롤러를 선언 할 수 있습니다.

편집 다음 templates / contacts.html을 상상해보십시오.

<div>
    <h3>Contacts</h3>
    <p>This is contacts page...</p>
</div>

위의 내용 routeProvider은 포함하는 div에 컨트롤러를 삽입합니다. 기본적으로 위의 html은 자동으로 다음과 같이됩니다.

<div ng-controller="ContactsCtrl">
    <h3>Contacts</h3>
    <p>This is contacts page...</p>
</div>

다른 컨트롤러를 가질 수 있다고 말하면 다음과 같이 컨트롤러를 내부 DOM 요소에 연결할 수 있습니다.

<div>
    <h3>Contacts</h3>
    <p ng-controller="anotherCtrl">Hello {{name}}! This is contacts page...     
    </p>
</div>

나는 이것이 일을 약간 명확히하기를 바랍니다.


따라서 <div ng-controller="FancyStuffController">이미 컨트롤러가 적용된 body 태그 안에 예를 들어 선언 <body ng-controller="BodyController">하면 작동할까요? $apply already in progress내가 이것을 할 때 오류가 발생 하지만 dpd.js와 관련이 있다고 생각합니다. 그것에 들어 가지 않기 위해, 나는 그것을 두 번 또는 무언가를로드한다고 생각합니다. 어떻게할지 모르겠지만 컨트롤러를 사용하여 다시로드하려고 할 수 있습니다.
blamb

1
@BrianThomas 물론입니다. 주의 : 뷰에 컨트롤러를 삽입하려면 $ routeProvider를 사용하고 div 태그에 ng-controller를 작성하지 마십시오.
Adhara는

9

현재 단일 페이지 애플리케이션을 구축하는 중입니다. 지금까지 귀하의 질문에 답할 것이라고 생각하는 내용이 있습니다. ng-view지시문 이있는 div가있는 기본 템플릿 (base.html)이 있습니다 . 이 지시문은 angular에 새 콘텐츠를 넣을 위치를 알려줍니다. 저는 angularjs를 처음 접했기 때문에 이것이 최선의 방법이라고 말하는 것은 아닙니다.

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

app.config(function($routeProvider, $locationProvider) {                        
  $routeProvider                                                                
       .when('/home/', {                                            
         templateUrl: "templates/home.html",                                               
         controller:'homeController',                                
        })                                                                      
        .when('/about/', {                                       
            templateUrl: "templates/about.html",     
            controller: 'aboutController',  
        }) 
        .otherwise({                      
            template: 'does not exists'   
        });      
});

app.controller('homeController', [              
    '$scope',                              
    function homeController($scope,) {        
        $scope.message = 'HOME PAGE';                  
    }                                                
]);                                                  

app.controller('aboutController', [                  
    '$scope',                               
    function aboutController($scope) {        
        $scope.about = 'WE LOVE CODE';                       
    }                                                
]); 

base.html

<html>
<body>

    <div id="sideMenu">
        <!-- MENU CONTENT -->
    </div>

    <div id="content" ng-view="">
        <!-- Angular view would show here -->
    </div>

<body>
</html>

실제로 index.html에서 main.html을 사용할 수 있도록 ng-view도 사용하고 있습니다. 그러나 / home 및 / about이 있고 두 컨트롤러는 각각 하나씩 있습니다. 내 main.html에 대한 ng-view와 함께 index.html 만 있습니다. 당신이 함께했던 것처럼 나는 main.html에 대한 두 개의 컨트롤러를 설정 카네when /home

이 게시물의 첫 번째 답변을 살펴보십시오 : stackoverflow.com/questions/17354568/…
Austin

글쎄, 나는 더 많은 것을 설정하는 방법을 알고 when있습니다. 단일 템플릿에 두 개의 컨트롤러가 필요합니다. 아니면 당신이 나에게 말하려는 것을 오해 했습니까?

컨트롤러를 사용하는 대신 지시문을 사용해보십시오. 단일 템플릿에 여러 지시문을 사용할 수 있습니다. 여전히 컨트롤러를 사용하려면 여기에 지시문이 컨트롤러와 연결되는 방법에 대한 비디오가 있습니다. egghead.io/lessons/angularjs-directives-talking-to-controllers
Austin

6
<div class="widget" ng-controller="widgetController">
    <p>Stuff here</p>
</div>

<div class="menu" ng-controller="menuController">
    <p>Other stuff here</p>
</div>
///////////////// OR ////////////


  <div class="widget" ng-controller="widgetController">
    <p>Stuff here</p>
    <div class="menu" ng-controller="menuController">
        <p>Other stuff here</p>
    </div>
</div>

menuController는 메뉴 div에 대한 액세스 권한이 있습니다. 그리고 widgetController는 둘 다에 액세스 할 수 있습니다.


이것은 간단 해 보이지만 찬성표가 없습니다. 이것이 최선의 방법입니까, 아니면 나쁜가요?
redfox05 2015

1
100 개 이상의 컨트롤러가 많은 페이지가 있다면 무엇을 할 것인가! ... 모호한 연습.
ArifMustafa 2018-06-30

3

동일한 모듈에서 둘 이상의 컨트롤러를 간단히 선언 할 수 있습니다. 예를 들면 다음과 같습니다.

  <!DOCTYPE html>
    <html>

    <head>
       <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js">
       </script>
      <title> New Page </title>


    </head> 
    <body ng-app="mainApp"> <!-- if we remove ng-app the add book button [show/hide] will has no effect --> 
      <h2> Books </h2>

    <!-- <input type="checkbox" ng-model="hideShow" ng-init="hideShow = false"></input> -->
    <input type = "button" value = "Add Book"ng-click="hideShow=(hideShow ? false : true)"> </input>
     <div ng-app = "mainApp" ng-controller = "bookController" ng-if="hideShow">
             Enter book name: <input type = "text" ng-model = "book.name"><br>
             Enter book category: <input type = "text" ng-model = "book.category"><br>
             Enter book price: <input type = "text" ng-model = "book.price"><br>
             Enter book author: <input type = "text" ng-model = "book.author"><br>


             You are entering book: {{book.bookDetails()}}
     </div>

    <script>
             var mainApp = angular.module("mainApp", []);

             mainApp.controller('bookController', function($scope) {
                $scope.book = {
                   name: "",
                   category: "",
                   price:"",
                   author: "",


                   bookDetails: function() {
                      var bookObject;
                      bookObject = $scope.book;
                      return "Book name: " + bookObject.name +  '\n' + "Book category: " + bookObject.category + "  \n" + "Book price: " + bookObject.price + "  \n" + "Book Author: " + bookObject.author;
                   }

                };
             });
    </script>

    <h2> Albums </h2>
    <input type = "button" value = "Add Album"ng-click="hideShow2=(hideShow2 ? false : true)"> </input>
     <div ng-app = "mainApp" ng-controller = "albumController" ng-if="hideShow2">
             Enter Album name: <input type = "text" ng-model = "album.name"><br>
             Enter Album category: <input type = "text" ng-model = "album.category"><br>
             Enter Album price: <input type = "text" ng-model = "album.price"><br>
             Enter Album singer: <input type = "text" ng-model = "album.singer"><br>


             You are entering Album: {{album.albumDetails()}}
     </div>

    <script>
             //no need to declare this again ;)
             //var mainApp = angular.module("mainApp", []);

             mainApp.controller('albumController', function($scope) {
                $scope.album = {
                   name: "",
                   category: "",
                   price:"",
                   singer: "",

                   albumDetails: function() {
                      var albumObject;
                      albumObject = $scope.album;
                      return "Album name: " + albumObject.name +  '\n' + "album category: " + albumObject.category + "\n" + "Book price: " + albumObject.price + "\n" + "Album Singer: " + albumObject.singer;
                   }
                };
             });
    </script>

    </body>
    </html>

2

앱에 대한 간단한 선언 하나만

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

그런 다음 하나의 서비스와 두 개의 컨트롤러를 구축했습니다.

각 컨트롤러에 대해 JS에 한 줄이 있습니다.

app.controller('EditableRowCtrl', function ($scope, CRUD_OperService) {

그리고 HTML에서 주변 div에 앱 범위를 선언했습니다.

<div ng-app="app">

및 각 컨트롤러 범위는 자체 주변 div (앱 div 내)에서 별도로

<div ng-controller="EditableRowCtrl">

이것은 잘 작동했습니다.


0

모든 템플릿보기를 기본 html 파일에 포함 할 수도 있습니다. 예를 들면 :

<body ng-app="testApp">
  <h1>Test App</h1>
  <div ng-view></div>
  <script type = "text/ng-template" id = "index.html">
    <h1>Index Page</h1>
    <p>{{message}}</p>
  </script>
  <script type = "text/ng-template" id = "home.html">
    <h1>Home Page</h1>
    <p>{{message}}</p>
  </script>
</body>

이렇게하면 각 템플릿에 다른 컨트롤러가 필요한 경우에도 앵귤러 라우터를 사용할 수 있습니다. 작동 예제는이 plunk를 참조하십시오. http://plnkr.co/edit/9X0fT0Q9MlXtHVVQLhgr?p=preview

이렇게하면 응용 프로그램이 서버에서 클라이언트로 전송되면 데이터 요청 등을 할 필요가 없다고 가정하여 완전히 자체 포함됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.