自己總結的尚矽谷Angular課程筆記 1.入門介紹 1.1AngularJS是什麼? jQuery是js函數庫 Angular是Google開源的JS結構化框架 官網:https://angularjs.org/ 1.1.1AngularJS特性和優點 耦合度越低越好,避免牽一發而動全身的事情發生 ...
自己總結的尚矽谷Angular課程筆記
1.入門介紹
1.1AngularJS是什麼?
jQuery是js函數庫
Angular是Google開源的JS結構化框架
官網:https://angularjs.org/
1.1.1AngularJS特性和優點
耦合度越低越好,避免牽一發而動全身的事情發生
1.1.2與jQuery比較
angular:在頁面和記憶體之間建立管道,讓數據在管道里來迴流動
1.1.3AngularJS能做什麼項目
構建單頁面(SPA)Web應用或Web App應用
1)單頁面應用(SPA):single page application
特點:
1.將所有的活動局限於一個頁面
2.當頁面中有部分數據發生了變化,不會刷新整個頁面,而是局部刷新
3.利用的是ajax技術、路由
2)
使用插件可以看到網頁里使用的angular相關數據
沒有使用angular會提示
1.1.4關於版本的問題
學的是1.*版本,而AngularJS還有2.*和4.*
1.*的版本採用的事JavaScript的語法
2.*和4.*用的事typescript的語法
1.2開發第一個AngularJS應用
1.2.1例子
實現效果:
1)jQuery實現
引入jQuery庫
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<input type="text" id="name">
<p>您輸入的內容是:<span id="contentSpan"></span></p>
<script type="text/javascript" src="../../js/jquery/jquery-1.11.1.js"></script>
<script type="text/javascript">
$(function () {//document.ready文檔載入完畢(頁面的結構) 原生:window.onload:整個頁面載入完畢,包括圖片。。。
$('#name').keyup(function () {
var name = this.value;
$('#contentSpan').html(name);
})
})
</script>
</body>
</html>
|
2)Angularjs實現
引入angularjs文件
<script src="../../js/angular-1.2.29/angular.js"></script>
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body ng-app>
<input type="text"
ng-model="username">
<p>您輸入的內容是:<span>{{username}}</span></p>
<script src="../../js/angular-1.2.29/angular.js"></script>
<script type="text/javascript">
</script>
</body>
</html>
|
3)理解第一個angularjs應用
1.2.2Webstorm設置
手動設置:
file→settings→editor→live templates
導入設置:
file→import settings
1.2.3引入AngularJS
使用<script>引用AngularJS源文件
1). 本地引入:
angularjs.js
2). 線上遠程引入(CDN):
http://cdn.bootcss.com/angular.js/1.5.5/angular.min.js
1.2.4使用AngularJS
在頁面中使用Angular的指令和表達式,在谷歌瀏覽器上使用ng-inspector插件
ng-app(指令) : 告訴angular核心它管理當前標簽所包含的整個區域,並且會自動創建$rootScope根作用域對象
ng-app生成的
ng-model : 將當前輸入框的值與誰關聯(屬性名:屬性值), 並作為當前作用域對象($rootScope)的屬性
{{}} (表達式) : 顯示數據,從當前作用域對象的指定屬性名上取
1、表達式:通常有一個返回值,可以放在任何需要值得地方,比如函數調用的參數,一個變數名,一個運算,
2、語句:通常表示一個完整的執行單位,一段完整的js可執行的代碼,有的語句也可以用表達式來執行,叫做表達式語句。
3、區別:語句用分號結尾,有些語句我們沒有加分號,比如console.log雖然我們沒有加分號,但也是語句,因為js引擎會自動解析並且加上分號。
4、特例:if語句,就不用加封號 可也是完整的語句
2.四個重要概念
2.1雙向數據綁定
2.1.1數據綁定
數據從一個地方A轉移(傳遞)到另一個地方B, 而且這個操作由框架來完成
- View(視圖):
頁面(標簽、指令,表達式)
- Model(模型) :作用域對象(屬性、方法)
- 數據綁定:
數據從一個位置自動流向另一個位置
- View-->Model
- Model-->View
- 單向數據綁定:
只支持一個方向
- View-->Model : ng-init
- Model-->View : {{name}}
- 雙向數據綁定
- Model<-->View : ng-model
- angular是支持雙向數據綁定的
2.1.2雙向數據綁定
數據可以從View(視圖層)流向Model(模型), 也可以從Model流向View
* 視圖(View): 也就是我們的頁面(主要是Andular指令和表達式)
* 模型(Model) : 作用域對象(當前為$rootScope), 它可以包含一些屬性或方法
* 當改變View中的數據, Model對象的對應屬性也會隨之改變: ng-model指令 數據從View==>Model
* 當Model域對象的屬性發生改變時, 頁面對應數據隨之更新: {{}}表達式 數據從Model==>View
* ng-model是雙向數據綁定, 而{{}}是單向數據綁定
對象是用來存放管理數據的,函數是特殊的對象,與對象不同的是,函數可以執行,對象里也可以包含函數
例子:
表達式只能用來顯示,不能操作,需要操作的地方就要使用ng-model指令
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>02_(雙向)數據綁定</title>
</head>
<body ng-app="" ng-init="name='tom'">
<input type="text"
ng-model="name">
<p>姓名1:{{name}}</p>
<input type="text" ng-model="name">
<p>姓名2:{{name}}</p>
<script type="text/javascript" src="../../js/angular-1.2.29/angular.js"></script>
</body>
</html>
|
2.1.3 ng-init
用來初始化當前作用域變數。日常開發不會全用這個初始化。
2.1.4理解雙向數據綁定
2.2依賴註入(DI,Dependency Injection)
* 依賴對象:完成某個特定的功能需要某個對象才能實現,這個對象就是依賴對象。
如何引入依賴對象?
方式一: 內部自己創建 : 不動態
方式二: 全局變數 : 污染全局命名空間
方式三: 形參引入依賴 : 依賴註入使用的方式,這種最好
* 依賴註入:1). 定義函數時, 使用形參聲明依賴對象變數,
在函數體中使用依賴對象(我們實現)
2). 函數調用時, 自動將創建好的依賴對象動態傳入(框架實現)
3). 例子: 事件監聽就使用了依賴註入, event就是依賴對象(event可以是任意名稱)
angular的
‘$scope’對象就是依賴對象,並且是依賴註入的形式進行使用。
回調函數的event的就是依賴對象,回調函數有形參就是依賴註入
Angular中的依賴註入:形參必須是特定的名稱$scope,
否則Angular無法註入會拋異常
開發的兩種方式:
需求:將數組裡的每一項值乘2,然後輸出
1.命令式
var arr = [1,2,3,4,5];
var newArr = [];
for(var i=0;i<arr.length;i++){
var num = arr[i]*2;
newArr.push(num);
}
console.log(newArr);
2.聲明式
//聲明式
var newArr2 = arr.map(function (item) {
return item*2;
});
console.log(newArr2);
命令式和聲明式的區別:
命令程式執行的時候每一步都是按照自己的指令,更註重執行的過程
聲明式更註重執行的結果。聲明式是對命令式的局部包裝
它們是解答題與填空題的區別
2.3 MVC模式
總結:
- M: Model, 即模型**, 在angular中:
- 為scope
- 儲存數據的容器
- 提供操作數據的方法
- **V: View, 即視圖**, 在angular中:
- 為頁面
- 包括:
html/css/directive/expression
- 顯示Model的數據
- 將數據同步到Model
- 與用戶交互
- **C: Controller, 即控制器**, 在angular中:
- 為angular的Controller
- 初始化Model數據
- 為Model添加行為方法
2.4 M-V-VM模式
MVVM是MVC的進化版, Angular使用的就是M-V-VM
在angular中MVVM模式主要分為四部分:
1. View:它專註於界面的顯示和渲染,在angular中則是包含一堆聲明式Directive的視圖模板。
2. Model:它是與應用程式的業務邏輯相關的數據的封裝載體,它是業務領域的對象,Model並不關心會被如何顯示或操作,所以模型也不會包含任何界面顯示相關的邏輯。也就是Angular中的Service
3. ViewModel:它是View和Model的粘合體,負責View和Model的交互和協作,它負責給View提供顯示的數據,以及提供了View中Command事件操作Model的途徑;也就是Angular中的scope
4. Controller:這並不是MVVM模式的核心元素,但它負責ViewModel對象的初始化,它將組合一個或者多個service來獲取業務領域Model放在ViewModel對象上,使得應用界面在啟動載入的時候達到一種可用的狀態。
總結:
- M: Model, 即數據模型, 在angular中:
- 為scope中的各個數據對象
- V: View, 即視圖, 在angular中:
- 為頁面
- VM: ViewModel, 即視圖模型, 在angular中:
- 為scope對象
- 在angular中controller不再是架構的核心,在MVVM中只是起輔助作用,用來輔助$scope對象,即VM層
3.三個重要對象
3.1作用域(scope)
作用域對象:
* 一個js實例對象, ng-app指令預設會創建一個根作用域對象($rootScope)
* 它的屬性和方法與頁面中的指令或表達式是關聯的
3.2控制器(controller)
* 用來控制AngularJS應用數據的 實例對象,是我們View與Model之間的橋梁
* ng-controller : 指定控制器構造函數,
Angular會自動new此函數創建控制器對象
* 同時Angular還有創建一個新的作用域對象$scope,
它是$rootScope的子對象
每定義一個ng-controller指令, 內部就會創建一個新的作用域對象($scope), 並自動註入構造函數中,在函數內部可以直接使用$scope對象。
* 在控制器函數中聲明$scope形參, Angular會自動將$scope對象傳入
3.3作用域與控制器
例子:
angular舊版本:手動寫構造器的方法已淘汰
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body ng-app="" ng-init="age=12">
<div ng-controller="MyController">
<input type="text"
placeholder="姓" ng-model="firstName">
<input type="text"
placeholder="名" ng-model="lastName">
<p>輸入的姓名為: {{firstName+'-'+lastName}}</p>
<p>輸入的姓名2為: {{getName()}}</p>
</div>
<div>
{{firstName}} <!--不能顯示-->
</div>
<script type="text/javascript" src="../../js/angular-1.2.29/angular.js"></script>
<script type="text/javascript">
function
MyController ($scope) {//必須是$scope
// alert(this instanceof
MyController);//說明是new調用
$scope.firstName = 'KB';
$scope.lastName
= 'Brent';
//給域對象指定方法
$scope.getName = function() {
return
$scope.firstName
+ " " +
$scope.lastName;
};
console.log($scope.age);
}
</script>
</body>
</html>
|
3.3模塊(module)
- 也是一個對象
- 創建模塊對象: angular.module('模塊名', [依賴的模塊])
- 通過模塊添加控制器:
-
module.controller('MyController', function($scope){//操作$scope的語句})
- angular的整體設計也是多模塊的
- 核心模塊:
angular.js
- 擴展模塊:
angular-router.js, angular-message.js, angular-animate.js
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body ng-app="MyApp">
<div ng-controller="MyCtrl">
<input type="text"
ng-model="empName">
<p>員工名:{{empName}}</p>
</div>
<div ng-controller="MyCtrl1">
<input type="text"
ng-model="empName">
<p>員工:{{empName}}</p>
</div>
<script type="text/javascript" src="../../js/angular-1.5.5/angular.js"></script>
<script type="text/javascript">
//
console.log(angular,typeof angular);
// //創建當前應用的模塊對象
// var module =
angular.module('MyApp',[]);
//
module.controller('MyCtrl',function ($scope) {
// $scope.empName = 'Tom';
// });
//
module.controller('MyCtrl1',function ($scope) {
// $scope.empName = 'Jack';
// })
寫法問題:代碼重覆率高。
//方法鏈調用
// angular.module('MyApp',[])//模塊對象的方法執行完返回的就是模塊對象本身
//
.controller('MyCtrl',function ($scope) {//$scope //寫法問題(js代碼壓縮時會把所有的局部變數壓縮成abcd等)
// $scope.empName =
'Tom';
//
}).controller('MyCtrl1',function ($scope) {
// $scope.empName =
'Jack';
// })
/*
上面寫法的問題:
1、形參只能寫固定的變數名$scope;
2、一旦文件壓縮,將不能使用,會報錯。
*/
//改進
angular.module('MyApp',[])
.controller('MyCtrl',['$scope',function (a) {
a.empName = 'tom'
}])
.controller('MyCtrl1',['$scope',function (b) {
b.empName
= 'Jack';
}])
</script>
</body>
</html>
|
4.兩個頁面語法
4.1表達式
- {{js表達式}}
- 從作用域對象中讀取對應的屬性數據來顯示數據
- 不支持if/for/while
- 支持三目表達式
4.2指令
- 什麼指令
: 自定義標簽屬性/標簽
- 常用的指令:
- ng-app: 指定模塊名,angular管理的區域
- ng-model: 雙向綁定,輸入相關標簽
- ng-init: 初始化數據
- ng-click: 調用作用域對象的方法(點擊時)
可以傳$event
- ng-controller: 指定控制器構造函數名,內部會自動創建一個新的子作用域(外部的)
- ng-bind: 解決使用{{}}顯示數據閃屏(在很短時間內顯示{{}})
- ng-repeat: 遍曆數組顯示數據, 數組有幾個元素就會產生幾個新的作用域
- $index, $first, $last,
$middle, $odd, $even
- ng-show: 布爾類型, 如果為true才顯示
- ng-hide: 布爾類型, 如果為true就隱藏
- ng-class: 動態引用定義的樣式 {aClass:true, bClass:false}
- ng-style: 動態引用通過js指定的樣式對象 {color:'red',
background:'blue'}
- ng-mouseenter: 滑鼠移入監聽, 值為函數調用, 可以傳$event
- ng-mouseleave: 滑鼠移出監聽, 值為函數調用, 可以傳$event
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body ng-app="myApp" >
<div ng-controller="MyCtrl" ng-init="age=12">
<div>
<h2>價格計算器(自動)</h2>
數量:<input type="number" ng-model="count1">
價格:<input type="number" ng-model="price1">
<p>總計:{{count1 * price1}}</p>
</div>
<div>
<h2>價格計算器(手動)</h2>
數量:<input type="number" ng-model="count2">
價格:<input type="number" ng-model="price2">
<button ng-click="getTotalPrice()">計算</button>
<p>總計:{{totalPrice}}</p>
</div>
<h3>人員信息列表</h3>
<ul>
<li ng-repeat="person in persons">偶數行:{{$even}},奇數行{{$odd}},中間的:{{$middle}},最後一個:{{$last}},第一個:{{$first}},第{{$index + 1}}個,{{person.name}}----{{person.age}}</li>
</ul>
<!--當使用ng-bind的時候表達式不再生效-->
<p ng-bind="count2">{{'asdfdsfds'}}</p>
<p>{{count2}}</p>
<button ng-click="switch()">切換</button>
<p ng-show="isLike">我喜歡賈靜雯</p>
<p ng-hide="isLike">賈靜雯喜歡我</p>
</div>
<script type='text/javascript' src='../../js/angular-1.5.5/angular.js'></script>
<script type='text/javascript'>
//創建模塊對象
angular.module('myApp', [])
.controller('MyCtrl', ['$scope', function ($scope) {
$scope.count1 = 1;
$scope.price1 = 20;
$scope.count2 = 1;
$scope.price2 = 10;
$scope.totalPrice = $scope.count2 * $scope.price2;
$scope.getTotalPrice
= function () {
$scope.totalPrice = this.price2 *
this.count2;
};
$scope.persons = [
{name : 'kobe', age : 39},
{name : 'anverson', age : 41},
{name : 'weide', age : 38},
{name : 'tim', age : 40},
{name : 'curry', age : 29}
];
$scope.isLike = true;
$scope.switch = function () {
$scope.isLike = !$scope.isLike;
}
}])
</script>
</body>
</html>
|
隔行換色
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<style>
.evenB
{
background-color: grey;
}
.oddB
{
background-color: green;
}
</style>
<body ng-app="myApp" ng-controller="MyController">
<div style="width: 100px;height:
100px;background-color: red"
ng-mouseover="over()" ng-mouseleave="leave()" ng-style="myStyle">
</div>
<div>
<ul>
<li ng-repeat="p in persons"
ng-class="{evenB:$even, oddB:$odd}">
{{p.name}}---{{p.age}}
</li>
</ul>
</div>
<script type='text/javascript' src="../../js/angular-1.5.5/angular.js"></script>
<script type="text/javascript">
angular.module('myApp', [])
.controller('MyController', function ($scope)
{
$scope.over
= function () {
$scope.myStyle = {
background: 'blue'
};
};
$scope.leave
= function () {
$scope.myStyle = {
background: 'green'
};
};
$scope.persons = [
{name: 'Tom',
age: 12},
{name: 'Tom2',
age: 13},
{name: 'Tom3',
age: 14},
{name: 'Tom4',
age: 15},
{name: 'Tom5',
age: 16}
];
});
</script>
</body>
</html>
|
4.3過濾器
- 作用: 在顯示數據時可以對數據進行格式化或過濾
- 單個--->格式化(將別的類型的數據轉換為特定格式的字元串)
- 多個----》格式化/過濾
- 不會真正改變被操作數據
- {{express | 過濾器名:補充說明}}
- 常用過濾器:
- currency 貨幣格式化(文本)
- number數值格式化(文本)
- date 將日期對象格式化(文本)
- json: 將js對象格式化為json(文本)
- lowercase : 將字元串格式化為全小寫(文本)
- uppercase : 將字元串格式化全大寫(文本)
- limitTo 從一個數組或字元串中過濾出一個新的數組或字元串
- limitTo : 3 limitTo : -3
- orderBy : 根據指定作用域屬性對數組進行排序
- {{[2,1,4,3] | orderBy}} 升序
- {{[2,1,4,3] | orderBy:‘-’}} 降序
- {{[{id:2,price:3},
{id:1, price:4}] | orderBy:'id'} id升序
- {{[{id:2,price:3},
{id:1, price:4}] | orderBy:'-price'} price降序
- filter : 從數組中過濾返回一個新數組
- {{[{id:22,price:35},
{id:23, price:45}] | filter:{id:'3'}} //根據id過濾
- {{[{id:22,price:35},
{id:23, price:45}] | filter:{$:'3'}} //根據所有欄位過濾
5.練習
練習1
遇到的問題:如果沒有保存就讀取報錯
①放空串,類型不對
②放空json對象,返回了類型並顯示到了輸入框
③放空數組,成功
總結:處理null的情況
【我的筆記.html】
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
textarea{
resize: none;
}
</style>
</head>
<body ng-app="noteApp" ng-controller="NoteController">
<h2>我的筆記</h2>
<textarea cols="30" rows="10" ng-model="message"></textarea>
<div>
<button ng-click="save()">保存</button>
<button ng-click="read()">讀取</button>
<button ng-click="delete()">刪除</button>
</div>
<p>剩餘字數:{{getCount()}}</p>
<script type="text/javascript" src="../../js/angular-1.5.5/angular.js"></script>
<script type="text/javascript" src="app.js"></script>
</body>
</html>
|
【app.js】
angular.module('noteApp', [])
.controller('NoteController', function ($scope)
{
//console.log($scope.message);
$scope.message = '';
//定義獲取剩餘字數的方法
$scope.getCount = function ()
{
//判斷輸入數據的長度
if(this.message.length
> 100){
$scope.message = $scope.message.slice(0,
100);
}
//返回剩餘字數的個數
return 100 - $scope.message.length;
};
//定義保存的方法
$scope.save = function ()
{
alert('note is saved');
//將數據保存到sessionStorage中
sessionStorage.setItem('note_key', JSON.stringify($scope.message));
//將輸入內容清空
$scope.message = '';
};
//定義讀取的方法
$scope.read = function ()
{
$scope.message = JSON.parse(sessionStorage.getItem('note_key') || '[]');//對讀取null做了處理
};
//
定義刪除的方法
$scope.delete = function ()
{
$scope.message = '';
};
});
|
練習2
unshift()
返回的是 新數組的length
相鄰的後邊的刪不掉,
①遞歸解決,不推薦
②逆向思維,保存未選中的到新數組
【demo.html】
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body ng-app="todoApp" >
<div ng-controller="TodoControl">
<h2>我的備忘錄</h2>
<div>
<input type="text"
ng-model="newTodo">
<button ng-click="add()">新增</button>
</div>
<div ng-repeat="todo in todos">
<input type="checkbox"
ng-model="todo.isChecked">
<span>{{todo.todo}}</span>
</div>
<button ng-click="delete()">刪除選中的記錄</button>
</div>
<script type="text/javascript" src="../../js/angular-1.5.5/angular.js"></script>
<script type="text/javascript" src="app.js"></script>
</body>
</html>
|
【app.js】
angular.module('todoApp', [])
.controller('TodoControl', function ($scope)
{
//初始化數據
$scope.todos = [
{todo
: '吃飯', isChecked : false},
{todo
: '睡覺', isChecked : false},
{todo
: '打豆豆', isChecked : false}
];
//定義添加todo的方法
$scope.add = function () {
//判斷添加的內容是否為空
if(!$scope.newTodo){
alert('輸入的內容不能空');
return
}
//
組合新的todo對象
var todo = {
todo
: $scope.newTodo,
isChecked
: false
};
//
將新的對象添加到todos中
$scope.todos.unshift(todo);
//添加完將輸入的內容清空
$scope.newTodo = '';
};
//定義刪除 todo 的方法
$scope.delete = function ()
{
//將$scope.todo的數據暫時保存
var oldTodo = $scope.todos;
//將$scope.todos的數據清空
$scope.todos = [];
//進行遍歷
oldTodo.forEach(function (item, index) {
//將沒被選中的todo添加到 $scope.todos 數組中
if(!item.isChecked){
$scope.todos.push(item);
}
});
}
});
|