web-dev-qa-db-ja.com

シングルページアプリでAngularJSを使用した複数のコントローラ

私が知りたいのは、単一ページのアプリケーションに対して複数のコントローラーを使用する方法です。私はそれを理解しようと試みました、そして私は私のものと非常によく似た質問を見つけました、しかしあなたが単一ページのアプリのために複数のコントローラーを使わないことに終わる特定の問題を解決するたくさんの異なった答えがあります。

1ページに複数のコントローラを使用するのは賢明ではないからでしょうか。それとも不可能ですか?

メインページを動かしているキックアスイメージカルーセルコントローラーが既にあるとしましょう、それから私はモーダルを使う方法を(例えば言おう)そして私はそれのために新しいコントローラーが必要です(または私がコントローラーを必要とする他のもの)。その後何をしますか?

私は他の質問に対するいくつかの回答を見てきました。彼らは私とほとんど同じことについて質問し、人々は「* OMG。なぜあなたはそれをやるのですか、ちょうどこれをしてください...」と答えます。

最善の方法は何ですか、またはどのようにしますか。

編集

あなたの多くは、単に2つのコントローラを宣言し、それを呼び出すために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を使うことができるのになぜ私はここでもコントローラを設定する必要があるのですか?これは私を混乱させたものです。 (そして、あなたはこのように2つのコントローラを追加することはできません、私は思う...)

97
user2539369

何が問題ですか?複数のコントローラを使用するには、複数の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
}
92
J. Bruni

私はあなたが "シングルページアプリ"の意味を逃していると思います。

これは、物理的に1つの.htmlがあることを意味するのではなく、1つのメインindex.htmlと複数のNESTED .htmlファイルがあることを意味します。それではなぜ単一ページのアプリ?これは、ページを標準的な方法でロードするのではなく(つまり、フルページを完全に更新するブラウザ呼び出し)、Angular/Ajaxを使用してコンテンツ部分をロードするためです。ページが変わるたびにちらつくことはありませんので、ページから移動しなかったという印象があります。したがって、あなたはあなたが単一のページにとどまっているように感じます。

今、私はあなたがあなたのSINGLE PAGEアプリのために複数のコンテンツを持ちたいと思っていると思います:(例)家、連絡先、ポートフォリオ、そして店。あなたのシングルページ/マルチコンテンツアプリ(角度のある方法)はこのように構成されます。

  • 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を呼び出します(注意してください: routes を使用している場合は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>

これで物事が少し明確になることを願っています。

A

91
Adhara

私は現在、単一ページのアプリケーションを作成中です。これが私があなたの質問に答えることになると私が信じているものです。 ng-viewディレクティブを含むdivを含む基本テンプレート(base.html)があります。このディレクティブは、新しいコンテンツをどこに置くべきかをangleに指示します。

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>
9
Austin
<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は両方にアクセスできます。

6
Muhammad Awais

私はちょうどアプリの一つの簡単な宣言を置く

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

それから私は1つのサービスと2つのコントローラーを作りました

各コントローラについて、私はJSの中に一行ありました

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

そしてHTMLでは、私は周囲のdivでアプリのスコープを宣言しました

<div ng-app="app">

そしてそれぞれのコントローラースコープは、それ自身の周囲のdivで別々に(アプリdiv内で)

<div ng-controller="EditableRowCtrl">

これはうまくいった

2
pat capozzi

同じモジュール内に複数のControllerを宣言するだけです。これが例です:

  <!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
Abdallah Okasha

すべてのテンプレートビューをメインの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

この方法では、アプリケーションがサーバーからクライアントに送信されると、データ要求などを行う必要がないと仮定して、完全に自己完結型になります。

0
Daimonos