动漫引擎

导航

Best Practice AngularJS

Best Practice AngularJS

 

/* 用几组简明扼要的代码段及其说明, 展示良好的编程行为, angularjs */

 

// app.module.js

angular

    .module('app', ['ngRoute']);

 

// logger.js

(function() {

    'use strict';

 

    angular

        .module('app')

        .factory('logger', logger);

 

    function logger() { }

})();

 

/*

 Single Responsibility 单一责任的文件,小函数

 * 1个组件, 1个文件, <400LOC (代码行)

 * Small Functions,小函数 < 75LOC(1屏幕), 易于重用,维护和测试

 

 用IIFE减少全局变量

 * 类和组件, 要包裹在IIFE里面, (立即执行的函数表达式) Immediately Invoked Function Expression .

 *减少全局变量, 从而减少这些变量的寿命,和重名

 

 Modules模块定义

 避免产生额外的全局变量:

 * 在定义module的时候, 用chain,不要用setter语法引入中间变量,

 * 在引用module的时候, 用chain + getter语法, 不定义中间变量。

 * 一个module只能创建1次, 多次引用

 * 用有名函数, 不要用callback, 以避免Nested的callback

 */

 

/* 在view中:

 <div ng-controller="CustomerProductController as ProductVm">

 <input ng-model="ProductVm.title"/>

 </div>

 */

 

angular

    .module('app')

    .controller('CustomerProductController', CustomerProductController);

 

CustomerProductController.$inject = ['dataservice', 'logger'];

 

function CustomerProductController($scope, dataservice, logger) {

    var vm = this;

    vm.refresh = refresh;

    vm.search = search;

    vm.sessions = [];

    vm.title = 'Sessions';

 

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

    function refresh() {

    }

 

    function search() {

    }

 

    $scope.$watch('vm.title', function(current, original) {

        $log.info('vm.title was %s', original);

        $log.info('vm.title is now %s', current);

    });

}

 

// route-config.js

angular

    .module('app')

    .config(config);

 

function config($routeProvider) {

    $routeProvider

        .when('/customerProduct', {

            templateUrl: 'customerProduct.html',

            controller: 'CustomerProductController',

            controllerAs: 'productVm'

        });

}

 

/*

 Controllers

 * 在view中用as语法代替$scope, 类似于new一个实例,接近本色的.语法., 避免$parent,

 * 在controller自身中, 用vm(view Modal)代替this,避免歧义,并减少$scope,(仅仅剩余在$emit, $broadcast, $on, $watch等少数情况下,必须用$scope)

 

 * 把bindable函数写在前面, 并按照字母排序, 具体的实现放在后面(如果实现只有1行,可以直接写)。

 让重要的函数一览无余, 而且与函数的顺序无关。

 * 薄controller, 厚service: 尽量把controller的逻辑下放到services,便于重用,和unit test

 * 让controller专注到1个view, 不要重用,因为UI经常变,(而让可重用部分下放给service)

 * 在route中定义controller和view,而避免在view中直接指定controller(绑死了),这样, 可以灵活地在route中重用view与controller。

 */

 

 

// service全部改用factory

angular

    .module('app')

    .service('logger', logger);

 

function logger() {

    this.logError = function(msg) {

    };

}

 

// factory

angular

    .module('app')

    .factory('logger', logger);

 

function logger() {

    return {

        logError: function(msg) {

        }

    };

}

 

/*

 Services

 * 用factory代替service,

 以简化,并保持一致性。

 因为,所有的service都是singleton,而且用new来实例化。

 */

 

function dataService($http, $location, $q, exception, logger) {

    var isPrimed = false;

    var primePromise;

 

    var service = {

        getAvengers: getAvengers,

        ready: ready

    };

 

    return service;

 

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

    function getAvengers() {

    }

 

    function ready(nextPromises) {

        // implementation details go here

    }

}

 

/*

 Factories

 * 与Controller一样的地方:(任务要单一, 接口函数放在前面)

 *  factory都是singleton, 返回的object包括了其所有接口函数

 */

 

 

// dataService.js

angular

    .module('app.core')

    .factory('dataService', dataService);

 

dataService.$inject = ['$http', 'logger'];

 

function dataService($http, logger) {

    return {

        getAvengers: getAvengers

    };

 

    function getAvengers() {

        return $http.get('/api/maa')

            .then(getAvengersComplete)

            .catch(getAvengersFailed);

 

        function getAvengersComplete(response) {

            return response.data.results;

        }

 

        function getAvengersFailed(error) {

            logger.error('XHR Failed for getAvengers.' + error.data);

        }

    }

}

 

// controller.js

angular

    .module('app.avengers')

    .controller('AvengersController', AvengersController);

 

AvengersController.$inject = ['dataService', 'logger'];

 

function AvengersController(dataService, logger) {

    var vm = this;

    vm.avengers = [];

 

    activate();

 

    function activate() {

        return getAvengers().then(function() {

            logger.info('Activated Avengers View');

        });

    }

 

    function getAvengers() {

        return dataService.getAvengers()

            .then(function(data) {

                vm.avengers = data;

                return vm.avengers;

            });

    }

}

 

/*

 Data操作全部用Service

 * 抽出data操作, 例如:http, local storage, db都纳入service中, (不要放在controller中)

 * 返回promise, 以利于chain操作

 */

 

 

// 对于controller和service

AvengersController.$inject = ['moviesPrepService'];

 

 

// 对于 route

function config($routeProvider) {

    $routeProvider

        .when('/avengers', {

            templateUrl: 'avengers.html',

            controller: 'AvengersController',

            controllerAs: 'vm',

            resolve: {

                moviesPrepService: moviesPrepService

            }

        });

}

 

moviesPrepService.$inject = ['movieService'];

function moviesPrepService(movieService) {

    return movieService.getMovies();

}

/*

 Manual Annotating for Dependency Injection: 手工注入, 让minify安全

 */

 

/*

 其余主题:

 Minification and Annotation: 注释,适合minify的

 Exception Handling

 

 */

 

/* Naming: 命名规范

 featureType.js

 */

 


用几个代码段, 和 简要的 原则注释, 来直观地展示编程好习惯。

angularjs1,2的
js的
dom的
类和子类的
module的


https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md
https://github.com/johnpapa/angular-styleguide/blob/master/i18n/zh-CN.md

posted on 2017-03-09 03:12  动漫引擎  阅读(154)  评论(0编辑  收藏  举报