ChatGPT解决这个技术问题 Extra ChatGPT

如何创建单独的 AngularJS 控制器文件?

我将所有 AngularJS 控制器都放在一个文件 controllers.js 中。该文件的结构如下:

angular.module('myApp.controllers', [])
  .controller('Ctrl1', ['$scope', '$http', function($scope, $http) {    
  }])
  .controller('Ctrl2', ['$scope', '$http', function($scope, $http) }
  }])

我想做的是将 Ctrl1 和 Ctrl2 放入单独的文件中。然后我会将这两个文件都包含在我的 index.html 中,但是应该如何构建呢?我尝试做这样的事情,它在网络浏览器控制台中抛出一个错误,说它找不到我的控制器。有什么提示吗?

我搜索了 StackOverflow 并发现了这个类似的问题 - 但是,这种语法在 Angular 之上使用了不同的框架(CoffeeScript),所以我无法遵循。

AngularJS: How do I create controllers in multiple files


F
Fresheyeball

档案一:

angular.module('myApp.controllers', []);

文件二:

angular.module('myApp.controllers').controller('Ctrl1', ['$scope', '$http', function($scope, $http){

}]);

文件三:

angular.module('myApp.controllers').controller('Ctrl2', ['$scope', '$http', function($scope, $http){

}]);

包括在该顺序中。我推荐 3 个文件,所以模块声明是独立的。

至于文件夹结构,这个主题有很多很多很多意见,但这两个还不错

https://github.com/angular/angular-seed

http://briantford.com/blog/huuuuuge-angular-apps.html


如果 OP 对 CoffeeScript 语法表示混淆,也许最好不要在你的答案中使用它?
@Andrew imho 未来的帮助和记录解决方案是 SO 的真正意义所在,而不是临时的 q 和 a。
@RuslanIsmagilov 您的 appCtrl 是一个全局 window.appCtrl。这不是一个好习惯。
@Fresheyeball,这种方法的问题是 index.html 中的导入顺序很重要,否则,Angular 会发出错误。
@hendryau,我正在使用 OP 中的模块名称。也就是说,有些人认为拥有多个名称空间模块而不是中央应用程序模块在组织上更好。
J
Jimmy Au

最后使用带有数组的 angular.module API 将告诉 angular 创建一个新模块:

myApp.js

// It is like saying "create a new module"
angular.module('myApp.controllers', []); // Notice the empty array at the end here

在没有数组的情况下使用它实际上是一个 getter 函数。因此,要分离您的控制器,您可以执行以下操作:

Ctrl1.js

// It is just like saying "get this module and create a controller"
angular.module('myApp.controllers').controller('Ctrlr1', ['$scope', '$http', function($scope, $http) {}]);

Ctrl2.js

angular.module('myApp.controllers').controller('Ctrlr2', ['$scope', '$http', function($scope, $http) {}]);

在您的 javascript 导入期间,只需确保 myApp.js 在 AngularJS 之后但在任何控制器/服务 / 等之前...否则 Angular 将无法初始化您的控制器。


我应该在哪里写我的依赖项。 var myapp = angular.module('demo', ['ngRoute','ngCookies','ui.bootstrap','nvd3ChartDirectives','ui-rangeSlider','textAngular','angularTreeview']);
@vipin 就像您键入的内容一样,但请确保它高于任何控制器、服务等。从技术上讲,您不需要声明 var myapp = ...;因为 Angular 会为您存储它。
@JimmyAu Ctrl1.js 和 Ctrl2.js 在哪里加载以便页面可以使用它?我在 Angular 之后加载了 myApp.js,但页面找不到控制器。我是否必须将它们显式添加为需要它的视图上的脚本?还是我仍然必须在每个页面上包含每个控制器文件?
感谢您澄清为什么只有第一个电话需要 []。
t
thank_you

虽然这两个答案在技术上都是正确的,但我想为这个答案引入不同的语法选择。这个恕我直言,可以更容易地阅读注射的情况,区分等等。

文件一

// Create the module that deals with controllers
angular.module('myApp.controllers', []);

文件二

// Here we get the module we created in file one
angular.module('myApp.controllers')

// We are adding a function called Ctrl1
// to the module we got in the line above
.controller('Ctrl1', Ctrl1);

// Inject my dependencies
Ctrl1.$inject = ['$scope', '$http'];

// Now create our controller function with all necessary logic
function Ctrl1($scope, $http) {
  // Logic here
}

文件三

// Here we get the module we created in file one
angular.module('myApp.controllers')

// We are adding a function called Ctrl2
// to the module we got in the line above
.controller('Ctrl2', Ctrl2);

// Inject my dependencies
Ctrl2.$inject = ['$scope', '$http'];

// Now create our controller function with all necessary logic
function Ctrl2($scope, $http) {
  // Logic here
}

有趣的是,它确实让我不用去多个文件来注册一个控制器
我看到很多这样的编码。有什么好处?让 $inject 和一个函数分开。
我相信它使代码更易于阅读。我知道到底注射了什么。将其视为逐行的“关注点分离”。
像这样的代码不仅产生更易读的代码,更容易调试,并且减少了嵌套回调代码的数量(参见 github.com/johnpapa/angular-styleguide/blob/master/a1/…
如果我可以 +1 这 1000 次,我会 - 太棒了!
A
Ahmed Mansour

这个解决方案怎么样? Modules and Controllers in Files(在页面末尾)它适用于多个控制器、指令等:

应用程序.js

var app = angular.module("myApp", ['deps']);

我的Ctrl.js

app.controller("myCtrl", function($scope) { ..});

html

<script src="app.js"></script>
<script src="myCtrl.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">

Google 还有一个Best Practice Recommendations for Angular App Structure,我非常喜欢按上下文分组。不是一个文件夹中的所有 html,而是例如用于登录的所有文件(html、css、app.js、controller.js 等)。所以如果我在一个模块上工作,所有的指令都更容易找到。


P
Pete TNT

为简洁起见,这是一个不依赖全局变量的 ES2015 示例

// controllers/example-controller.js

export const ExampleControllerName = "ExampleController"
export const ExampleController = ($scope) => {
  // something... 
}

// controllers/another-controller.js

export const AnotherControllerName = "AnotherController"
export const AnotherController = ($scope) => {
  // functionality... 
}

// app.js

import angular from "angular";

import {
  ExampleControllerName,
  ExampleController
} = "./controllers/example-controller";

import {
  AnotherControllerName,
  AnotherController
} = "./controllers/another-controller";

angular.module("myApp", [/* deps */])
  .controller(ExampleControllerName, ExampleController)
  .controller(AnotherControllerName, AnotherController)

如果您使用命名函数,您可以节省相当多的输入。它们有方便的属性 name.. 所以您可以简单地使用 ExampleCtrl.name 而不是重复 .. 重复它。
我不能让它工作。 plnkr.co/edit/… - 模块“myApp”不可用!
u
user3682640

不是那么优雅,但实现解决方案非常简单 - 使用全局变量。

在“第一个”文件中:


window.myApp = angular.module("myApp", [])
....

在“第二”、“第三”等:


myApp.controller('MyController', function($scope) {
    .... 
    }); 

我使用此代码但仍然无法加载我的控制器?它抛出错误:错误:[ng:areq] 参数 'ProductCtrl' 不是函数,未定义。
这是非常糟糕的做法
@Kim Jong Un 如果您不将控制器添加/连接到您创建的模块,您将看到该错误。因此,如果您使用以下语法,它将起作用:angular.module('myApp').controller('ProductCtrl', ['$scope', '$http', function($scope, $http){ //Your ProductCtrl code goes here }]);
@Brendan,简单地说某事是不好的做法总比没有好-但不多。告诉我们为什么这是不好的做法会帮助其他人。