使用 routeProvider 的模板的多个控制器

Posted

技术标签:

【中文标题】使用 routeProvider 的模板的多个控制器【英文标题】:Multiple controllers for a template using routeProvider 【发布时间】:2014-03-08 19:19:51 【问题描述】:

我开始使用 AngularJS 开发我的第一个大项目,当我在考虑应用程序的设计时,我发现了一些我不明白的地方。

我在考虑单页应用程序,所以我使用 ng-view 和 routeProvider 将每个查询路由到正确的模板和控制器。但是,我的一些模板有点复杂,我首先想到的是使用不同的控制器来管理每个模板。也就是说,同一模板的不同部分将由不同的控制器管理。问题(或者至少,我认为是问题)是 routeProvider 只允许将一个模板关联到一个控制器。这让我觉得除了我在路由配置中使用 routeProvider 指定的控制器之外,我不能将另一个控制器用于模板。

然后我开始想办法重组未来的项目,这样我就可以在由单个控制器管理的同一模板中维护每个不同的功能,并且仍然让它们之间的控制器交互。

在头疼之后,我决定尝试实施我的第一种方法,看看它是如何失败的,然后……真是惊喜!它工作得很好!但是,我不知道确切的原因。

让我给你看这个简单的例子:

script.js

angular.module('myApp', [
  'ngRoute'
])
  .config(function ($routeProvider, $locationProvider) 
    $routeProvider
      .when('/', 
        templateUrl: 'main',
        controller: 'MainCtrl' 
      );

    $locationProvider.html5Mode(true);
  );

angular.module('myApp')
  .controller('MainCtrl', function ($scope) 
    // whatever...
    );
  );

angular.module('myApp')
  .controller('FirstCtrl', function ($scope) 
      $scope.first = function()
           alert("First");
      ;
    );
  );

angular.module('myApp')
  .controller('SecondCtrl', function ($scope) 
      $scope.second= function()
           alert("Second");
      ;
    );
  );

ma​​in.html

<div ng-controller="FirstCtrl">
    <button ng-click="first()">First!</button>
</div>

<div ng-controller="SecondCtrl">
    <button ng-click="second()">Second!</button>
</div>

index.html

<body ng-app="myApp">
    <div ng-view=""></div>
</body>

我想如果你配置路由以将“main”模板关联到“MainCtrl”控制器,那将是唯一与模板交互的控制器,但事实并非如此。

我一开始以为找不到“first”和“second”函数,因为在路由配置中没有声明“FirstCtrl”和“SecondCtrl”。我想也许 routeProvider 会“包装”(或类似的东西)“主”模板和“MainCtrl”控制器,而“主”模板将无法访问其余的控制器。

但这不正确,来自不同控制器的“第一”和“第二”功能正常工作。那么,在路由配置中为模板指定控制器有什么意义?您可以只设置一个模板来呈现指定的查询,并且该模板可以使用模块的任何控制器。

也许这不是一个好的设计,我不知道。

您能帮我更好地理解这一点吗?

谢谢!

【问题讨论】:

这正是我此刻的困境。就我而言,我将 Yeoman 与 Angular 生成器(它为您引导路由)一起使用,并且某些模板需要多个控制器。我会采用你的方法,但我很想知道你是保留它还是转移到其他东西。谢谢! 【参考方案1】:

如您所说,使用 $route 提供程序时:

.config(function ($routeProvider, $locationProvider) 
$routeProvider
  .when('/', 
    templateUrl: 'main',
    controller: 'MainCtrl' 
  );

$locationProvider.html5Mode(true);  );

您实际上是使用 MainCrtl'./' 路由中的所有内容包装起来。

因此,当您在 &lt;div ng-view=&gt;&lt;/div&gt; 中注入 Main.html 视图时,您会得到以下渲染:

 <body ng-app="myApp">
    <div ng-controller='MainCtrl'>    
       <div ng-controller="FirstCtrl">
       <button ng-click="first()">First!</button>
       </div>

       <div ng-controller="SecondCtrl">
       <button ng-click="second()">Second!</button>
       </div>
    </div>

 </body>

【讨论】:

【参考方案2】:

真的,重点是您不必在视图中执行&lt;div ng-controller="MyCtrl"&gt;。这可能有一些优势,例如视图可以为不同的上下文保存不同的数据,但仍然是相同的 html。

【讨论】:

以上是关于使用 routeProvider 的模板的多个控制器的主要内容,如果未能解决你的问题,请参考以下文章

AngularJS 具有相同模板的多个路由不应重新渲染

如何使用 Angular js 示例解决 routeProvider 问题?

angularjs 路由可以有可选的参数值吗?

可以禁用 $locationProvider 和 $routeProvider 吗?

angularjs $routeProvider 不包括视图(未知提供者)

创建通用控制器功能