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