我想知道如何为单页应用程序使用多个控制器。我试图解决这个问题并且我发现了与我的问题非常相似的问题,但是在解决特定问题时只有大量不同的答案,您最终没有为单个页面应用程序使用多个控制器。
这是因为对单个页面使用多个控制器是不明智的吗?或者这是不可能的?
让我们说我已经在主页上有一个kick-ass图像轮播控制器,但后来我学会了如何(让他们说)使用模态,我也需要一个新的控制器(或者我需要控制器的任何其他东西)。那我该怎么办?
我已经看到了其他问题的一些答案,他们问我几乎和我一样的事情,人们回答" * 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,为什么我甚至需要在这里设置一个控制器?这让我很困惑。 (并且你不能用这种方式添加两个控制器,我认为......)
答案 0 :(得分:91)
我认为你错过了“单页应用”的含义。
这并不意味着你将拥有一个.html,而是你将拥有一个主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将正确的控制器传递给它(请注意:如果使用路径,则不要在ng-controller
中指定contacts.html
指令)
然后,当然,您可以在contacts.html页面中声明尽可能多的ng-controller指令。那些将是ContactCtrl
的子控制器(因此继承它)。但是对于单个路径,在routeProvider
内,您可以声明一个控制器,它将充当“部分视图的父控制器”。
EDIT 想象一下以下模板/ 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
答案 1 :(得分:90)
有什么问题?要使用多个控制器,只需使用多个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 :(得分:9)
我目前正在构建单页面应用程序。到目前为止,我认为这将是回答你的问题。我有一个基本模板(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>
答案 3 :(得分: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可以访问这两者。
答案 4 :(得分:2)
我只是简单地声明了应用
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">
这很好用
答案 5 :(得分: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>
答案 6 :(得分: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>
这样,如果每个模板需要不同的控制器,那么您仍然可以使用角度路由器。 请参阅此插件以获取工作示例 http://plnkr.co/edit/9X0fT0Q9MlXtHVVQLhgr?p=preview
这样一旦应用程序从服务器发送到您的客户端,它就完全自包含,假设它不需要发出任何数据请求等。