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

我想知道的是如何使用多个控制器的单个页面的应用程序。 我试图弄清楚,我发现了与我的非常相似的问题,但只有一堆不同的答案解决了一个特定的问题,你最终不使用多个控制器的单个页面的应用程序。

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

比方说,我已经有一个工作在主页面上的图像旋转木马控制器,但是我学会了如何使用模式,而且我还需要一个新的控制器(或者其他需要控制器的东西)。 那我该怎么办?

我看到了一些其他问题的答案,他们问我几乎和我一样的事情,人们回答说:“你为什么要这样做,就这样做…”。

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

编辑

你们中的许多人正在回答只声明两个控制器,然后使用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? 这使我困惑。 (你不能这样添加两个控制器,我想…)

问题是什么? 要使用多个控制器,只需使用多个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一样简单:

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

我想你错过了“单页面应用程序”的含义。

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

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

  • index.html :包含标题, <ng-view>和页脚
  • contacts.html :包含联系表单(无标题,无页脚)
  • portfolio.html :包含投资组合数据(没有页眉没有页脚)
  • store.html :包含商店,没有页眉没有页脚。

你在索引中,你点击名为“contacts”的菜单,会发生什么? Angular用contacts.html代码replace<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传递正确的控制器(请注意: 如果您使用路由,不要在contacts.html指定ng-controller指令

那么当然,你可以在你的contacts.html页面中声明很多的ng-controller指令。 那些将是ContactCtrl子控制器(从而inheritance它)。 但是对于routeProvider的单个路由,您可以声明一个控制器作为“局部视图的父控制器”。

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

我希望这个澄清一点。

一个

我目前正在build立一个单页面应用程序。 到目前为止,我相信会回答你的问题。 我有一个基本模板(base.html),其中有一个div与ng-view指令。 这个指令告诉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> 
 <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可以同时访问这两个。

我只是把一个简单的应用程序的声明

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

然后我build立了一个服务和两个控制器

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

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

而在HTML中,我宣布应用程序范围在周围的股利

 <div ng-app="app"> 

和每个控制器范围分别在自己的周围div(在应用程序div)

 <div ng-controller="EditableRowCtrl"> 

这工作得很好

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

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

这样如果每个模板需要不同的控制器,那么你仍然可以使用angular度路由器。 看到这个plunk的工作示例http://plnkr.co/edit/9X0fT0Q9MlXtHVVQLhgr?p=preview

这样,一旦应用程序从服务器发送到您的客户端,它是完全独立的,假设它不需要做任何数据请求等。