2016/1/17 20:09
规范1:
//不推荐
angular
.module('app', ['ngRoute'])
.controller('SomeController', SomeController)
.factory('someFactory', someFactory);
function SomeController() { }
function someFactory() { }
**推荐1**
// app.module.js
angular
.module('app', ['ngRoute']);
// some.controller.js
angular
.module('app')
.controller('SomeController', SomeController);
function SomeController() { }
// someFactory.js
angular
.module('app')
.factory('someFactory', someFactory);
function someFactory() { }
在推荐1中有一个问题,那就是function暴露在window下,像这样
/* 不推荐*/
// 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() { }
/**
* 推荐
*
* 将不会存在全局变量
*/
// 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() { }
})();
规范2
/* 不推荐 */
var app = angular.module('app', [
'ngAnimate',
'ngRoute',
'app.shared',
'app.dashboard'
]);
/* 推荐(使用简单的语法)*/
angular
.module('app', [
'ngAnimate',
'ngRoute',
'app.shared',
'app.dashboard'
]);
规则:3
//避免
angular
.module('app')
.controller('DashboardController', function() { })
.factory('logger', function() { });
//推荐
// dashboard.js
angular
.module('app')
.controller('DashboardController', DashboardController);
function DashboardController() { }
// logger.js
angular
.module('app')
.factory('logger', logger);
function logger() { }
规范4
使用 controllerAs 语法、
<div ng-controller="CustomerController">
{{ name }}
div>
<div ng-controller="CustomerController as customer">
{{ customer.name }}
div>
/* avoid */
function courseController (){
this.name = 'course';
this.customers = [
{name: 'Haley'}, {name: 'Ella'}, {name: 'Landon'}, {name: 'John'}
];
}
angular.module('app')
.controller('courseController', courseController)
/* 推荐*/
function courseController (){
var vm = this;
vm.name = 'course';
vm.customers = [
{name: 'Haley'}, {name: 'Ella'}, {name: 'Landon'}, {name: 'John'}
];
}
angular.module('app')
.controller('courseController', courseController)
/* 避免*/
function SessionsController() {
var vm = this;
vm.gotoSession = function() {
/* ... */
};
vm.refresh = function() {
/* ... */
};
vm.search = function() {
/* ... */
};
vm.sessions = [];
vm.title = 'Sessions';
}
/* 推荐*/
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() {
/* */
}
}
规范5
/**
* avoid
* Using function expressions.
*/
function AvengersController(avengersService, logger) {
var vm = this;
vm.avengers = [];
vm.title = 'Avengers';
var activate = function() {
return getAvengers().then(function() {
logger.info('Activated Avengers View');
});
}
var getAvengers = function() {
return avengersService.getAvengers().then(function(data) {
vm.avengers = data;
return vm.avengers;
});
}
vm.getAvengers = getAvengers;
activate();
}
/*
* recommend
* Using function declarations
* and bindable members up top.
*/
function AvengersController(avengersService, logger) {
var vm = this;
vm.avengers = [];
vm.getAvengers = getAvengers;
vm.title = 'Avengers';
activate();
function activate() {
return getAvengers().then(function() {
logger.info('Activated Avengers View');
});
}
function getAvengers() {
return avengersService.getAvengers().then(function(data) {
vm.avengers = data;
return vm.avengers;
});
}
}
延迟逻辑。保持控制器苗条
/* avoid */
function OrderController($http, $q, config, userInfo) {
var vm = this;
vm.checkCredit = checkCredit;
vm.isCreditOk;
vm.total = 0;
function checkCredit() {
var settings = {};
// Get the credit service base URL from config
// Set credit service required headers
// Prepare URL query string or data object with request data
// Add user-identifying info so service gets the right credit limit for this user.
// Use JSONP for this browser if it doesn't support CORS
return $http.get(settings)
.then(function(data) {
// Unpack JSON data in the response object
// to find maxRemainingAmount
vm.isCreditOk = vm.total <= maxRemainingAmount
})
.catch(function(error) {
// Interpret error
// Cope w/ timeout? retry? try alternate service?
// Re-reject with appropriate error for a user to see
});
};
}
/* recommended */
function OrderController(creditService) {
var vm = this;
vm.checkCredit = checkCredit;
vm.isCreditOk;
vm.total = 0;
function checkCredit() {
return creditService.isOrderTotalOk(vm.total)
.then(function(isOk) { vm.isCreditOk = isOk; })
.catch(showError);
};
}
**
确保一个控制器对应一个view ,相同逻辑应该放在服务service中,尽量确保控制器的简洁;
**
服务返回一个对象
服务的定义语法糖
// service
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) {
/* */
}
};
}
angular.
module('myServiceModule', []).
controller('MyController', ['$scope','notify', function ($scope, notify) {
$scope.callNotify = function(msg) {
notify(msg);
};
}]).
factory('notify', ['$window', function(win) {
var msgs = [];
return function(msg) {
msgs.push(msg);
if (msgs.length == 3) {
win.alert(msgs.join("\n"));
msgs = [];
}
};
}]);
angualr.module('app').
factory('dataService',dataService)
function dataService() {
var someValue = '';
var service = {
save: save,
someValue: someValue,
validate: validate
};
return service;
/隐藏函数实现的细节///
function save() {
/* */
};
function validate() {
/* */
};
}
**
指令
**
用指令的名字命名文件名字
将一个指令单独放在一个文件中
在指令中操作dom
定义指令的时候:最好定义一个清晰独一无二的名字像这样
acmeSalesCustomerInfo 在html中运用的时候需要这样写
acme-sales-customer-info
/* avoid */
/* directives.js */
angular
.module('app.widgets')
/* order directive that is specific to the order module */
.directive('orderCalendarRange', orderCalendarRange)
/* sales directive that can be used anywhere across the sales app */
.directive('salesCustomerInfo', salesCustomerInfo)
/* spinner directive that can be used anywhere across apps */
.directive('sharedSpinner', sharedSpinner);
function orderCalendarRange() {
/* implementation details */
}
function salesCustomerInfo() {
/* implementation details */
}
function sharedSpinner() {
/* implementation details */
}
/* recommended */
/* calendar-range.directive.js */
/**
* @desc order directive that is specific to the order module at a company named Acme
* @example
*/
angular
.module('sales.order')
.directive('acmeOrderCalendarRange', orderCalendarRange);
function orderCalendarRange() {
/* implementation details */
}
/* recommended */
/* customer-info.directive.js */
/**
* @desc sales directive that can be used anywhere across the sales app at a company named Acme
* @example
*/
angular
.module('sales.widgets')
.directive('acmeSalesCustomerInfo', salesCustomerInfo);
function salesCustomerInfo() {
/* implementation details */
}
/* recommended */
/* spinner.directive.js */
/**
* @desc spinner directive that can be used anywhere across apps at a company named Acme
* @example
*/
angular
.module('shared.widgets')
.directive('acmeSharedSpinner', sharedSpinner);
function sharedSpinner() {
/* implementation details */
}
定义指令的时候,建议restrict: ‘EA’;因为这样会有语义化,而class就没有了;向下面这样
/* recommended */
angular
.module('app.widgets')
.directive('myCalendarRange', myCalendarRange);
function myCalendarRange() {
var directive = {
link: link,
templateUrl: '/template/is/located/here.html',
restrict: 'EA'
};
return directive;
function link(scope, element, attrs) {
/* */
}
}
/* better */
// route-config.js
angular
.module('app')
.config(config);
function config($routeProvider) {
$routeProvider
.when('/avengers', {
templateUrl: 'avengers.html',
controller: 'AvengersController',
controllerAs: 'vm',
resolve: {
moviesPrepService: function(movieService) {
return movieService.getMovies();
}
}
});
}
// avengers.js
angular
.module('app')
.controller('AvengersController', AvengersController);
AvengersController.$inject = ['moviesPrepService'];
function AvengersController(moviesPrepService) {
var vm = this;
vm.movies = moviesPrepService.movies;
}
/**
* recommended
*/
// controllers
avengers.controller.js
avengers.controller.spec.js
// services/factories
logger.service.js
logger.service.spec.js
// constants
constants.js
// module definition
avengers.module.js
// routes
avengers.routes.js
avengers.routes.spec.js
// configuration
avengers.config.js
// directives
avenger-profile.directive.js
avenger-profile.directive.spec.js
用于展示一个功能的文件都放在一根文件夹目录
/**
* recommended
*/
app/
app.module.js
app.config.js
components/
calendar.directive.js
calendar.directive.html
user-profile.directive.js
user-profile.directive.html
layout/
shell.html
shell.controller.js
topnav.html
topnav.controller.js
people/
attendees.html
attendees.controller.js
people.routes.js
speakers.html
speakers.controller.js
speaker-detail.html
speaker-detail.controller.js
services/
data.service.js
localstorage.service.js
logger.service.js
spinner.service.js
sessions/
sessions.html
sessions.controller.js
sessions.routes.js
session-detail.html
session-detail.controller.js
Use $document and $window instead of document and window.
Use $timeout and $interval instead of setTimeout and setInterval .