我有一个非常简单的AngularJS SPA,使用UI路由器在两个视图之间切换。单击Home链接后,用户将看到一行文本。 About链接应该相同,但其路由配置为使用templateUrl而不是模板字符串:
$stateProvider
.state("home", {
url: "/home",
template: "<h3>This is the Home content</h3>"
})
.state("about", {
url: "/about",
templateUrl: "about.html",
controller: "aboutController"
});
about.html就是这么简单:
<!DOCTYPE HTML>
<html ng-app="simpleApp">
<head>
<title>About</title>
<script src="aboutcontroller.js"></script>
</head>
<body ng-controller="aboutController">
<h3>{{message}}</h3>
</body>
</html>
......它的控制器也是一个简单的设计模板:
console.log("Registered aboutController"); ///////////
angular.module("simpleApp")
.controller("aboutController", ["$scope", function ($scope) {
console.log("Created aboutController"); ///////////
$scope.message = "This is the About content!";
}]);
请注意帮助我诊断问题的两个控制台语句。
问题:执行控制器脚本文件时,永远不会调用控制器本身。因此,用户不会看到文本,而是看到:
{{消息}}
这似乎与我在模板文件(about.html)中包含脚本文件的事实有关。如果我将脚本标记移动到index.html,问题就会消失,一切都按预期工作。
Here's a plunker that shows my problem and workaround.
真正的问题: 在这个非常简单和人为的例子中,将所有控制器脚本包含在SPA的主页中是合理的。但是对于一个非常简单的Web应用程序,可能有几十个页面都有几十个控制器。将所有控制器添加到主页面将无法很好地扩展性能,并且无法很好地进行维护。
那么设置它的适当方法是什么?如何/在何处包含控制器脚本?
编辑:我忘了提到我收到的错误(是的,我知道)。使用about.html中的脚本标记,我收到一条消息说
参数'aboutController'不是函数,未定义
这在控制台消息“Registered aboutController”之后直接发生。如果我移动脚本标记以在index.html中包含控制器,则不会显示错误。同样,对我而言,这表明控制器根本无法及时调用。移至index.html,它在需要时完全注册。
答案 0 :(得分:1)
这里是正常指定视图时的样子:
$stateProvider.state("home", {
url: "",
views: {
// Other views...
"client": {
templateUrl: "clientselection.html",
controller: "ClientSelectController",
controllerUrl: "Controllers/ClientSelect.controller"
}
}
});
这与angularAMD的内容相同。不同之处在于控制器现在按需加载:
$stateProvider.state("home", {
url: "",
views: {
// Other views...
"client": angularAMD.route({
templateUrl: "clientselection.html",
controller: "ClientSelectController",
controllerUrl: "Controllers/ClientSelect.controller"
})
}
});
值得一提的是Dan Wahlin's terrific blog post。它没有使用UI路由器,但概念是可转移的。不幸的是,帖子只提供了不完整的片段。其余的你需要从他在Github上传的庞大的样本项目中挑选出来。我不理解为什么需要这样做,但博客文章仍然值得一读。
答案 1 :(得分:0)
对于以角度进行路由,你应该使用routeProvider然后你可以像这样用它来导航:
var app = angular.module('moduleName', [
'ngRoute',
'angularModalService'
]);
app.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/home', {
templateUrl: 'partials/home.html',
controller: 'homeController'
}).otherwise({
redirectTo: '/home'
});
在这里你将homeController绑定到整个home.html,但是如果你需要将一个控制器绑定到页面的一小部分,你可以像这样绑定它:
<div class="row" ng-controller="homeController">
//Further HTML
</div>
控制器仅在此div中可用。
对于包含部分,我通常会在</body>
标记上方定义所有脚本。我将它们分开,首先是像jQuery和AngularJS这样的库,首先是app.js(带有routeProvoder的文件),控制器,然后是服务/工厂和最后的指令
答案 2 :(得分:0)
为了回答你的问题,Angular的设计方式是它加载所有的js文件并将控件赋予角度。加载Js文件时,所有控制器,服务等都在ngApp中注册。这就是为什么建议在index.html本身提供所有脚本文件的原因。
如果您认为在单个index.html中提供所有文件是笨拙的,那么您可以将应用程序拆分为模块然后加载它们。这是让您的应用看起来不那么笨拙的更好方法。