• 不要在控制器里操作 DOM。通过指令完成。
    • 通过控制器完成的功能命名控制器 (如:购物卡,主页,控制板),并以字符串Ctrl结尾。控制器采用驼峰命名法 (HomePageCtrl, ShoppingCartCtrl, AdminPanelCtrl, etc.).
    • 控制器不应该在全局中定义 (尽管 AngularJS 允许,但污染全局空间是个糟糕的实践)。
    • 使用一下语法定义控制器:
    1. function MyCtrl(dependency1, dependency2, ..., dependencyn) {
    2. // ...
    3. }
    4. module.controller('MyCtrl', MyCtrl);

    使用这种定义方式可以最大的避免问题。你可以使用工具自动生成数组定义,如:ng-annotate (and grunt task grunt-ng-annotate).

    • 使用控制器依赖的原名。这将提高代码的可读性:
    1. function MyCtrl(s) {
    2. // ...
    3. }
    4. module.controller('MyCtrl', ['$scope', MyCtrl]);

    下面的代码更易理解

    1. function MyCtrl($scope) {
    2. // ...
    3. }
    4. module.controller('MyCtrl', ['$scope', MyCtrl]);

    对于包含大量代码的需要上下滚动的文件尤其适用。这可能使你忘记某一变量是对应哪一个依赖。

    • 尽可能的精简控制器。将通用函数抽象为独立的服务。
    • 通过方法引用进行跨控制器通讯 (通常是子控制器与父控制器通讯) 或者 $emit, $broadcast$on 方法。发送或广播的消息应该限定在最小的作用域。
    • 制定一个通过 $emit, $broadcast 发送的消息列表并且仔细的管理以防命名冲突和bug。
    • 在需要格式化数据时将格式化逻辑封装成 过滤器 并将其声明为依赖:
    1. function myFormat() {
    2. return function () {
    3. // ...
    4. };
    5. }
    6. module.filter('myFormat', myFormat);
    7. function MyCtrl($scope, myFormatFilter) {
    8. // ...
    9. }
    10. module.controller('MyCtrl', MyCtrl);
    • 当内嵌的控制器 使用 "内嵌 scoping" ( controllerAs 语法):

    app.js

    1. module.config(function ($routeProvider) {
    2. $routeProvider
    3. .when('/route', {
    4. templateUrl: 'partials/template.html',
    5. controller: 'HomeCtrl',
    6. controllerAs: 'home'
    7. });
    8. });

    HomeCtrl

    1. function HomeCtrl() {
    2. this.bindingValue = 42;
    3. }

    template.html

    1. <div ng-bind="home.bindingValue"></div>