johnpapa/angular-styleguide权威解读:从入门到精通的编码规范

johnpapa/angular-styleguide权威解读:从入门到精通的编码规范

【免费下载链接】angular-styleguide johnpapa/angular-styleguide: 由John Papa创建的一份Angular编程风格指南,提供了遵循最佳实践的建议,帮助开发者编写高质量、可维护的Angular应用程序代码。 项目地址: https://gitcode.***/gh_mirrors/an/angular-styleguide

你是否在开发Angular应用时遇到过代码混乱、难以维护的问题?是否在团队协作中因编码风格不一致而效率低下?本文将为你详细解读由John Papa创建的这份Angular编程风格指南,帮助你从入门到精通Angular编码规范,编写高质量、可维护的Angular应用程序代码。读完本文,你将了解到Angular应用开发的最佳实践、命名规范、文件结构等关键内容,让你的代码更加规范、高效。

项目概述

本项目是由John Papa创建的一份Angular编程风格指南,提供了遵循最佳实践的建议,帮助开发者编写高质量、可维护的Angular应用程序代码。该指南得到了Angular团队的认可,Igor Minar(Angular团队负责人)对其进行了审查、提供了反馈,并委托John Papa负责这份指南。

官方文档:README.md

版本选择

Angular有多个版本,因此也有多个版本的指南。你需要根据自己使用的Angular版本选择相应的指南。

Angular 1 Style Guide

如果你使用的是Angular 1版本,可以参考The Angular 1 Style Guide。

Angular 2 Style Guide

对于Angular 2版本,The Angular 2 Style Guide已移至官方Angular 2文档,但本项目中仍保留了相关内容。

Angular 1编码规范详解

单一职责原则

每个文件一个组件

Style [Y001]建议每个文件只定义一个组件,代码行数最好少于400行。这样做有以下好处:

  • 便于单元测试和模拟
  • 更易于阅读、维护,避免团队在版本控制中发生冲突
  • 避免隐藏的bug,如组件共享变量、创建不必要的闭包或与依赖项的不必要耦合

以下是不推荐和推荐的代码示例对比:

不推荐的写法:

/* avoid */
angular
    .module('app', ['ngRoute'])
    .controller('SomeController', SomeController)
    .factory('someFactory', someFactory);

function SomeController() { }

function someFactory() { }

推荐的写法:

// app.module.js

/* re***mended */
angular
    .module('app', ['ngRoute']);

// some.controller.js

/* re***mended */
angular
    .module('app')
    .controller('SomeController', SomeController);

function SomeController() { }

// some.factory.js

/* re***mended */
angular
    .module('app')
    .factory('someFactory', someFactory);

function someFactory() { }
小函数原则

Style [Y002]建议定义小函数,不超过75行代码(越少越好)。小函数具有以下优点:

  • 更容易测试,特别是当它们只做一件事并服务于一个目的时
  • 促进代码重用
  • 更易于阅读和维护
  • 避免因大型函数共享外部作用域变量、创建不必要的闭包或与依赖项的不必要耦合而产生的隐藏bug

立即执行函数表达式(IIFE)

JavaScript作用域

Style [Y010]建议将Angular组件包装在立即执行函数表达式(IIFE)中。这样可以将变量从全局作用域中移除,防止变量和函数声明在全局作用域中存在过长时间,避免变量冲突。当代码被压缩并捆绑到单个文件部署到生产服务器时,IIFE可以防止变量冲突和过多的全局变量。

不推荐的写法:

/* avoid */
// logger.js
angular
    .module('app')
    .factory('logger', logger);

// logger function is added as a global variable
function logger() { }

// storage.js
angular
    .module('app')
    .factory('storage', storage);

// storage function is added as a global variable
function storage() { }

推荐的写法:

/**
 * re***mended
 *
 * no globals are left behind
 */

// logger.js
(function() {
    'use strict';

    angular
        .module('app')
        .factory('logger', logger);

    function logger() { }
})();

// storage.js
(function() {
    'use strict';

    angular
        .module('app')
        .factory('storage', storage);

    function storage() { }
})();

模块

避免命名冲突

Style [Y020]建议使用带有分隔符的唯一命名约定来命名子模块。唯一的名称有助于避免模块名称冲突,分隔符有助于定义模块及其子模块层次结构。例如,app可能是根模块,而app.dashboardapp.users可能是用作app依赖项的模块。

模块定义(设置器)

Style [Y021]建议使用设置器语法声明模块,不使用变量。因为每个文件一个组件,很少需要为模块引入变量。

不推荐的写法:

/* avoid */
var app = angular.module('app', [
    'ngAnimate',
    'ngRoute',
    'app.shared',
    'app.dashboard'
]);

推荐的写法:

/* re***mended */
angular
    .module('app', [
        'ngAnimate',
        'ngRoute',
        'app.shared',
        'app.dashboard'
    ]);
模块获取(获取器)

Style [Y022]建议在使用模块时,避免使用变量,而是使用获取器语法进行链式调用。这样可以生成更具可读性的代码,避免变量冲突或泄漏。

不推荐的写法:

/* avoid */
var app = angular.module('app');
app.controller('SomeController', SomeController);

function SomeController() { }

推荐的写法:

/* re***mended */
angular
    .module('app')
    .controller('SomeController', SomeController);

function SomeController() { }
设置与获取

Style [Y023]强调模块只应创建一次,然后从那时起获取。

/* re***mended */
// to set a module
angular.module('app', []);

// to get a module
angular.module('app');
命名函数与匿名函数

Style [Y024]建议使用命名函数,而不是将匿名函数作为回调传递。这样可以生成更具可读性的代码,更容易调试,并减少嵌套回调代码的数量。

不推荐的写法:

/* avoid */
angular
    .module('app')
    .controller('DashboardController', function() { })
    .factory('logger', function() { });

推荐的写法:

// dashboard.js

/* re***mended */
angular
    .module('app')
    .controller('DashboardController', DashboardController);

function DashboardController() { }

// logger.js

angular
    .module('app')
    .factory('logger', logger);

function logger() { }

控制器

controllerAs视图语法

Style [Y030]建议使用controllerAs语法,而不是经典的带有$scope的控制器语法。controllerAs语法更接近JavaScript构造函数的语法,促进在视图中绑定到"点分"对象(例如customer.name而不是name),更具上下文,更易于阅读,并避免没有"点分"可能出现的引用问题,还有助于避免在具有嵌套控制器的视图中使用$parent调用。

不推荐的写法:

<!-- avoid -->
<div ng-controller="CustomerController">
    {{ name }}
</div>

推荐的写法:

<!-- re***mended -->
<div ng-controller="CustomerController as customer">
    {{ customer.name }}
</div>
controllerAs控制器语法

Style [Y031]和Style [Y032]建议在控制器中使用controllerAs语法,并为this使用捕获变量,选择一致的变量名,例如vm(代表ViewModel)。this关键字是上下文相关的,当在控制器内的函数中使用时,其上下文可能会改变。捕获this的上下文可以避免遇到此问题。

不推荐的写法:

/* avoid */
function CustomerController($scope) {
    $scope.name = {};
    $scope.sendMessage = function() { };
}

/* avoid */
function CustomerController() {
    this.name = {};
    this.sendMessage = function() { };
}

推荐的写法:

/* re***mended */
function CustomerController() {
    var vm = this;
    vm.name = {};
    vm.sendMessage = function() { };
}
可绑定成员置顶

Style [Y033]建议将可绑定成员放在控制器的顶部,按字母顺序排列,不要分散在控制器代码中。这样可以轻松阅读,并帮助你立即识别控制器中哪些成员可以绑定并在视图中使用。将内联匿名函数定义为一行代码时可以放在顶部,但如果函数超过一行代码,将其放在可绑定成员下方可以提高可读性。

不推荐的写法:

/* avoid */
function SessionsController() {
    var vm = this;

    vm.gotoSession = function() {
      /* ... */
    };
    vm.refresh = function() {
      /* ... */
    };
    vm.search = function() {
      /* ... */
    };
    vm.sessions = [];
    vm.title = 'Sessions';
}

推荐的写法:

/* re***mended */
function SessionsController() {
    var vm = this;

    vm.gotoSession = gotoSession;
    vm.refresh = refresh;
    vm.search = search;
    vm.sessions = [];
    vm.title = 'Sessions';

    ////////////

    function gotoSession() {
      /* */
    }

    function refresh() {
      /* */
    }

    function search() {
      /* */
    }
}
将控制器逻辑委托给服务

Style [Y035]建议通过委托给服务和工厂来延迟控制器中的逻辑。将逻辑放在服务中并通过函数公开,可由多个控制器重用;服务中的逻辑更容易在单元测试中隔离,而控制器中的调用逻辑可以轻松模拟;还可以消除依赖关系,并对控制器隐藏实现细节,使控制器保持精简和专注。

服务和工厂

服务

Style [Y040]指出服务是使用new关键字实例化的,使用this表示公共方法和变量。由于服务和工厂非常相似,为了一致性,建议使用工厂。

服务示例:

// service
angular
    .module('app')
    .service('logger', logger);

function logger() {
  this.logError = function(msg) {
    /* */
  };
}
工厂

Style [Y050]和Style [Y051]强调工厂应该有单一职责,并且是单例的,返回一个包含服务成员的对象。

工厂示例:

// factory
angular
    .module('app')
    .factory('logger', logger);

function logger() {
    return {
        logError: function(msg) {
          /* */
        }
   };
}

项目资源

代码片段

本项目提供了多种编辑器的Angular代码片段,方便开发者快速编写符合规范的代码:

  • Brackets代码片段
  • Emacs代码片段
  • Sublime Text代码片段
  • Vim代码片段
  • VSCode代码片段
  • WebStorm实时模板

国际化

项目提供了多种语言的翻译版本,可在a1/i18n/目录下查看,方便不同地区的开发者学习和使用。

总结

John Papa的Angular风格指南为开发者提供了全面的编码规范和最佳实践,遵循这些规范可以帮助我们编写高质量、可维护的Angular应用程序代码。从单一职责原则到模块管理,从控制器设计到服务使用,每一个细节都旨在提高代码的可读性、可维护性和可扩展性。

希望本文对你理解和应用这份权威的Angular风格指南有所帮助。如果你有任何问题或建议,欢迎在项目仓库中提出。同时,也欢迎你点赞、收藏本文,关注后续更多关于Angular开发的优质内容!

社区教程:a1/i18n/zh-***.md

【免费下载链接】angular-styleguide johnpapa/angular-styleguide: 由John Papa创建的一份Angular编程风格指南,提供了遵循最佳实践的建议,帮助开发者编写高质量、可维护的Angular应用程序代码。 项目地址: https://gitcode.***/gh_mirrors/an/angular-styleguide

转载请说明出处内容投诉
CSS教程网 » johnpapa/angular-styleguide权威解读:从入门到精通的编码规范

发表评论

欢迎 访客 发表评论

一个令你着迷的主题!

查看演示 官网购买