Angularjs開發的一些方法和建議整理
1、如何使用yeoman快速的構建一個Angularjs環境
1.1、安裝node/npm
sudo apt-get install nodejs
*注意:
1 有些時候安裝nodejs後在/usr/bin/只有一個nodejs可執行檔案,但是很多包包括node的指令碼使用的是node,所以需要手動的建立一個node
sudo ln -s /usr/bin/nodejs /usr/bin/node
2 有些時候安裝源裡面沒有包含npm包,需要獨立安裝
sudo apt-get install npm
tar -xvf node-v*.tar.gz
./configure
make
sudo make install
1.2、全域性安裝grunt-cli和bower以及yeoman
sudo npm install -g grunt-cli bower yeoman
sudo npm install -g generator-karma generator-angular
1.3、初始化一個angular開發環境
yo angular Test
在這個過程會提示您是否使用sass以及選擇angular相關的組建。
這樣,一個angular開發環境初始化工作就完成了。
2、如何使用angular構建web app
2.1、建議使用的angular組織結構
▾ app/
▾ common/
▾ dialog/
▸ providers/
▸ templates/
dialogModule.js
▾ form/
▸ directives/
▸ styles/
▸ templates/
formModule.js
▸ rest/
▸ table/
▸ toastr/
▸ tooltips/
▾ container/
▾ config/
router.js
▾ controllers/
containerConsoleController.js
containerController.js
containerCreateController.js
containerDetailController.js
▸ directives/
▾ styles/
container.css
▾ templates/
console.html
container.html
create.html
detail.html
containerModule.js
▸ home/
▸ image/
▸ overview/
▸ pics/
404.html
favicon.ico
index.html
- 如上所示,common包中包含各個提取出來的通用的angular包,每個包包含自己獨立的module、directives、filters、services、providers、templates、styles等。這樣可以很好的利用angular模組化思想特性,利於抽取common中的包作為多專案的公用包。
- 除開common包,每一個子app如container、image、overview都是一個獨立的包,同樣包中包含自己獨立的module、config、controllers、directives、filters、services、providers、templates、styles,angular提供的函式注入功能可以很好的實現各個子應用之間的隔離與獨立。
2.2、關於module的使用
module主要定義這個子app的唯一名稱,所依賴的包,如:
angular.module('dockerEasyUiApp',
['overview',
'container',
'image',
'rest',
'table',
'dialog',
'form',
'toastr',
'tooltip',
'ngRoute',
'ngTouch',
'ngAnimate',
'ngResource',
'ngCookies'
]);
2.3、關於config的使用
config一般來說會定義包中一些全域性配置,如路由配置
angular.module('container').config(['$routeProvider', '$locationProvider',
function indexRouteConfig($routeProvider, $locationProvider) {
// Disable HTML5 mode (use # for routing)
$locationProvider.html5Mode(false);
var APP_NAME = "Docker easy UI";
// Configure each possible route
$routeProvider
// Container screen
.when('/container', {
title : APP_NAME,
templateUrl : 'container/templates/container.html',
controller : 'containerController'
})
// Image detail screen
.when('/container/:id', {
title : APP_NAME,
templateUrl : 'container/templates/detail.html',
controller : 'containerDetailController'
})
.when('/container/:id/console', {
title : APP_NAME,
templateUrl : 'container/templates/console.html',
controller : 'containerConsoleController'
})
}]);
如http headers配置
/**
* The config block for setting up the HTTP method.
*/
angular.module('dockerEasyUiApp').config(['$httpProvider',
function httpCommonConfig($httpProvider) {
$httpProvider.defaults.headers.common = {
'Content-Type': 'application/json'
}
}]);
2.4、關於services使用
services一般定義的是為controllers服務的方法,如通常web app中的資料來源於伺服器端,需要走http請求,service端可以是對提供http資料請求的封裝,如
angular.module('rest').factory('imageService', ['$injector',
function imageService($injector) {
// Required services
var $http = $injector.get('$http');
// Get required types
var service = {};
/**
* Makes a request to the REST API to get the list of images,
* returning a promise that provides an array of @link{ImageSample} objects if
* successful.
*
* @param {Object.<Stirng, String>} queryOps
* The set of query options to filter with.
*
* @returns {Promise.<ImageSample[]>}
* A promise which will resolve with an array of @link{ImageSample} objects
* upon success.
*/
service.index = function index(queryOps) {
// Retrieve Servers
return $http({
method : 'GET',
url : '/images/json',
params : queryOps
});
};
/**
* Makes a request to the REST API to get image by id,
* returning a promise that provides an @link{ImageSample} object if
* successful.
*
* @param {Object.<Stirng, String>} queryOps
* The set of query options to filter with.
*
* @returns {Promise.<ImageSample>}
* A promise which will resolve with an @link{ImageSample} object
* upon success.
*/
service.show = function show(queryOps) {
// Retrieve Servers
return $http({
method : 'GET',
url : '/images/' + queryOps.id + '/json'
});
};
/**
* Makes a request to the REST API to get image by id,
* returning a promise that provides an @link{ImageSample} object if
* successful.
*
* @param {Object.<Stirng, String>} queryOps
* The set of query options to filter with.
*
* @returns {Promise.<ImageSample>}
* A promise which will resolve with an @link{ImageSample} object
* upon success.
*/
service.search = function search(searchVal) {
// Retrieve Servers
return $http({
method : 'GET',
url : '/images/search?term=' + searchVal
});
};
/**
* Makes a request to the REST API to delete a image,
* returning a promise that provides an Object.<String, String>
* if successful.
*
* @param {String} id
* The id of image.
*
* @returns {Promise.<Object>}
* A promise which will resolve with an object upon success.
*/
service.del = function del(id) {
var url = '/images/' + id;
// Retrieve Servers
return $http({
method : 'DELETE',
url : url
});
};
return service;
}]);
Tips:一般在用組建時,為了保持格式的簡潔一致,通暢使用$inject
,然後通過$inject.get(“ServiceName”)
獲取想要使用的方法。在定義的依賴裡面講所有的依賴都寫出來,顯得比較的臃腫,如
angular.module('test').controller('testController', ['$scope', '$http', '$q', '$timeout', '$router','$location'
function imageService($scope, $http, $q, $timeout, $router, $location) {
....
]);
推薦的優雅的方法是
angular.module('test').controller('testController', ['$scope', '$injecteor'
function imageService($scope, $injector) {
var $http = $injector.get("$http");
var $q = $injector.get("$q");
var $timeout = $injector.get("$timeout");
var $router = $injector.get("$router");
var $location = $injector.get("$location");
....
]);
2.5、關於controller使用
controller被定義為view和data互動的中間樞紐,既然是樞紐,所有controller中更應該體現邏輯,如
angular.module('image').controller('imageController', ['$scope', '$injector',
function indexController($scope, $injector) {
// Get image service.
var imageService = $injector.get("imageService");
var $dialog = $injector.get("$dialog");
var $route = $injector.get("$route");
var toastr = $injector.get("toastr");
// Define image table columns.
$scope.imageTableData = {
checkboxHeader: false,
singleSelect: true,
columns: [{
field: 'isSelected',
checkbox: true
}, {
field: 'Id',
title: 'ID',
visible: false
}, {
field: 'NamesLink',
title: 'Repostry Tags',
align: 'left',
valign: 'middle',
sortable: true
}, {
field: 'Size',
title: 'Size',
align: 'right',
valign: 'middle',
sortable: true
}, {
field: 'VirtualSize',
title: 'Virtual Size',
align: 'right',
valign: 'middle',
sortable: true
}, {
field: 'ParentId',
title: 'Parent',
align: 'left',
valign: 'middle'
}, {
field: 'Created',
title: 'Created',
align: 'left',
valign: 'middle',
sortable: true
}],
data: []
};
// Get image list.
imageService.index({all: 0})
.success(function(images) {
angular.forEach(images, function(ele, index) {
images[index].NamesLink = "<a class='' href='#/image/" +
images[index].Id + "'>" + images[index].RepoTags + "</a>";
});
$scope.imageTableData.data = images;
});
// Set image create event.
$scope.AddImage = function AddImage() {
$dialog.open({
templateUrl: 'image/templates/create.html',
controller: 'imageAddController'
});
};
// Handle image delete action.
$scope.Del = function Del(mode) {
if(!$scope.selectedItem) return;
var selectedItem = $scope.selectedItem;
//angular.forEach($scope.selectedItems || [], function(ele) {
imageService.del(selectedItem.Id).success(function (){
$route.reload();
toastr.success("Successfully delete image " + selectedItem.RepoTags);
});
//});
}
}]);
如上,controller更著重於呼叫服務,處理view的顯示以及響應view層的事件邏輯。
Tips:一般說來,不太建議在controller中呼叫類似於$(selector).method()
這樣的方法,angular一個很重要的思路就是讓開發者從繁雜的dom物件處理中解脫出來!!!但是也有例外,比如處理一些頁面效果時如果使用了jquery外掛,可能需要用到$(selector).method()
,但一般這些程式碼體現在directives中。
2.6、關於filters使用
filter第一為處理view顯示的方法,如格式化時間
<div>{{'2012-12-12T12:12:12'|datetime 'YY-MM-DD HH-mm-ss'}}</div>
然後定義一個directive方法處理時間
angular.module('test').filter('datatime', function() {
return function(text) {
// handle time formate.
}
});
Tips:一般說來,不太建議在controller中過多的處理源資料,而是通過定義filter來處理