首页 文章

在单页面应用程序中使用AngularJS的多个控制器

提问于
浏览
94

我想知道如何为单个页面应用程序使用多个控制器 . 我试图解决这个问题并且我发现了与我的问题非常相似的问题,但是解决特定问题的答案很多,最终你没有为单个页面应用程序使用多个控制器 .

那是因为对一个页面使用多个控制器是不明智的吗?或者它是不可能的?

假设我已经有一个kick-ass图像轮播控制器在主页面上工作,但后来我学会了如何(让我们说)使用模态,我也需要一个新的控制器(或者我需要一个控制器的任何其他东西) . 那我该怎么办?

我已经看到了其他问题的一些答案,他们问我几乎和我一样的事情,人们回答“* OMG . 你为什么要这样做,就这样做......” .

什么是最好的方式,或者你是如何做到的?

Edit

你们中的许多人正在回答声明两个控制器,然后使用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,为什么我甚至需要在这里设置一个控制器呢?这让我很困惑 . (你不能这样添加两个控制器,我想...)

7 回答

  • 2

    问题是什么?要使用多个控制器,只需使用多个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
    }
    
  • 9

    我认为你错过了“单页应用”的含义 .

    这并不意味着你将有一个.html,而是你将有一个主 index.html 和几个NESTED .html文件 . 那么为什么单页应用呢?因为这样您不会以标准方式加载页面(即完全刷新整页的浏览器调用),而只是使用Angular / Ajax加载内容部分 . 由于您没有看到页面更改之间的闪烁,因此您会觉得您没有从页面移动 . 因此,您觉得您只是呆在一个页面上 .

    现在,我假设您想为您的SINGLE PAGE应用程序提供多个内容:(例如)家庭,联系人,投资组合和商店 . 您的单页/多内容应用(角度方式)将以这种方式组织:

    • index.html :包含 Headers , <ng-view> 和页脚

    • contacts.html :包含联系表单(无 Headers ,无页脚)

    • portfolio.html :包含投资组合数据(无 Headers 无页脚)

    • store.html :包含商店,没有 Headers 没有页脚 .

    你在索引中,你点击名为"contacts"的菜单,会发生什么? Angular用 contacts.html 代码替换 <ng-view> 标记

    你是如何实现这一目标的?和 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传递正确的控制器(请注意: do not specify ng-controller directive in contacts.html if you are using routes

    然后,当然,您可以在contacts.html页面中声明尽可能多的ng-controller指令 . 那些将是 ContactCtrl 的子控制器(因此继承它) . 但是对于单个路径,在 routeProvider 内,您可以声明一个将充当"Father controller of the partial view"的Controller .

    编辑想象一下以下模板/ 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>
    

    我希望这会澄清一些事情 .

    一个

  • 88

    我目前正在构建单页面应用程序 . 到目前为止,我认为这将是回答你的问题 . 我有一个基本模板(base.html),其中包含一个带有 ng-view 指令的div . 这个指令告诉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>
    
  • 0
    <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

    我只是简单地声明了应用程序

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

    然后我构建了一个服务和两个控制器

    对于每个控制器,我在JS中有一条线

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

    在HTML中,我在周围的div中声明了应用范围

    <div ng-app="app">
    

    并且每个控制器的范围分别在它们自己的周围div中app div)

    <div ng-controller="EditableRowCtrl">
    

    这很好

  • 2

    我们可以简单地在同一个模块中声明多个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>
    
  • 90

    您还可以将所有模板视图嵌入到主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>
    

    这样,如果每个模板需要不同的控制器,那么您仍然可以使用角度路由器 . 请参阅此插件以获取工作示例http://plnkr.co/edit/9X0fT0Q9MlXtHVVQLhgr?p=preview

    这样一旦应用程序从服务器发送到您的客户端,它就完全自包含,假设它不需要发出任何数据请求等 .

相关问题