1. 頁面元素的控制
1.1 調(diào)用element 方法控制DOM元素
??使用Angular 框架開發(fā)應(yīng)用時(shí),盡量不要直接通過Javascript 代碼直接操作DOM元素,也不要引入Jquery 來操作DOM元素,而是通過Angular內(nèi)部的jQLite 來實(shí)現(xiàn):
??angular.element()element
<div ng-controller='myController' id='control'>
<button ng-click='add()'>添加元素</button>
<button ng-click='del()'>刪除元素</button>
</div>
<script type="text/javascript">
var app=angular.module('myapp',[]);
app.controller('myController',['$compile','$scope',function($compile,$scope){
$scope.hello='hello Angular!';
$scope.log=function(){
console.log('這是動(dòng)態(tài)添加的方法!');
};
var html="<div ng-click='log()'>{{hello}}</div>";
//生成一個(gè)Jquery對象
var template=angular.element(html);
//對生成的Jquery對象進(jìn)行編譯
var newHtml=$compile(template)($scope);
$scope.add=function(){
angular.element(document.getElementById('control')).append(newHtml);
}
$scope.del=function(){
if(newHtml){
newHtml.remove()
}
}
}]);
</script>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
??上述代碼中,控制器中注入了$compile 服務(wù),目的是初始化相關(guān)的依賴,并對生成的Jquery對template進(jìn)行編譯,以便于調(diào)用append方法。
1.2 解決setTimeout 改變屬性的無效
??在Angular中,大部分操作之后的效果都由$apply 方法自動(dòng)在頁面中完成,如果直接調(diào)用非Angular中的方法或函數(shù),例如setTimeout 方法,那么系統(tǒng)就不會(huì)調(diào)用$apply 方法,導(dǎo)致方法執(zhí)行失敗。
??有兩種方法可以解決:
- 在setTimeout方法中,將執(zhí)行的函數(shù)或表達(dá)式包含在
$apply 方法中
setTimeout(function(){
scope.apply(function(){
$scope.tip=’歡迎來到Angular世界!’;
})
},1000)
- 直接調(diào)用與setTimeout方法對應(yīng)的
$timeout 服務(wù)
$timeout(function(){
??$scope.tip=’歡迎來到Angular世界!’;
},1000)
1.3 解決雙大括號綁定元素時(shí)的閃爍問題
在Angular內(nèi)部,可以向元素中添加ng-clock 屬性來實(shí)現(xiàn)元素的隱藏效果:
<div ng-clock>{{message}}</div>
如果是綁定純文字的內(nèi)容,建議使用ng-bind 的方式,而非雙大括號:
<div ng-bind="message"></div>
2. 使用ng-repeat 時(shí)的注意事項(xiàng)
2.1
- 如果有過濾器,調(diào)用
$index 并不能準(zhǔn)確定位到對應(yīng)的記錄。
解決方案:使用其他的定位方式,例如元素的id等。
- 調(diào)用ng-repeat指令重新請求數(shù)據(jù)時(shí),并不是在原來的DOM元素中更新數(shù)據(jù),而是再次新建DOM元素。
解決方案:使用track by 排序ng-repeat中的數(shù)據(jù):
user in users track by user.id
- 在通過ng-repeat指令生成的子元素中,如果通過父元素的scope對象更新數(shù)據(jù)時(shí),不能直接更新遍歷的數(shù)據(jù)源,而必須逐個(gè)更新。
2.2 正確理解ng-repeat指令中的scope繼承關(guān)系
??在調(diào)用ng-repeat 指令顯示數(shù)據(jù)時(shí),ng-repeat 在新建DOM元素時(shí),也為每個(gè)新建的DOM元素創(chuàng)建了獨(dú)立的scope作用域。
??盡管如此,但它們的父級scope作用域是相同的,都是構(gòu)建控制器時(shí)注入的$scope 對象,調(diào)用angular.element(domElement).scope 方法可以獲取某個(gè)DOM元素所對應(yīng)的作用域,通過某個(gè)DOM元素所對應(yīng)的作用域又可以訪問到他的父級作用域,從而修改綁定的數(shù)據(jù)源。
<div ng-controller='myController'>
<input type="button" value="按鈕1" ng-click='change1()' />
<input type="button" value="按鈕2" ng-click='change2()' />
<input type="button" value="按鈕3" ng-click='change3()' />
<ul>
<li ng-repeat='user in users track by user.id'>
<span id="spn{{user.id}}">{{user.id}}</span>
<span>{{user.name}}</span>
<span>{{user.score}}</span>
</li>
</ul>
</div>
<script type="text/javascript">
var app=angular.module('myapp',[]);
app.controller('myController',['$scope',function($scope){
$scope.users=[
{id:1010,name:'zhangsan',score:10},
{id:1020,name:'lisi',score:60},
{id:1030,name:'wangwu',score:90}
];
$scope.change1=function(){
var scop1=angular.element(document.getElementById('spn1010')).scope();
var scop2=angular.element(document.getElementById('spn1020')).scope();
console.log(scop1==scop2);//false
};
$scope.change2=function(){
var scope=angular.element(document.getElementById('spn1020')).scope();
console.log(scope.$parent==$scope);//true
};
$scope.change3=function(){
var scope=angular.element(document.getElementById('spn1030')).scope();
scope.$parent.users=[
{id:1040,name:'wanger',score:'80'},
{id:1050,name:'zhaoliu',score:'900'}
];
}
}]);
</script>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
3. 解決單擊按鈕事件中的冒泡現(xiàn)象
??與在Javascript中一樣,都可以使用stopPropagation() 方法,在Angular中:
??$event.stopPropagation()
4. 釋放多余的$watch 檢測函數(shù)
??在Angular中,當(dāng)$watch 函數(shù)被調(diào)用時(shí),將返回一個(gè)釋放$watch 綁定的unbind 函數(shù),因此,只需要再次調(diào)用這個(gè)$watch 函數(shù)機(jī)具款有釋放其檢測功能。
<div ng-controller='myController'>
<input type="text" ng-model='content' />
<div>第{{num}}次變化</div>
<button ng-click='stopWatch()'>停止檢測</button>
</div>
<script type="text/javascript">
var app=angular.module('myapp',[]);
app.controller('myController',['$scope',function($scope){
$scope.num=0;
$scope.stopWatch=function(){
contentWatch();
}
var contentWatch=$scope.$watch('content',function(newVal,oldVal){
//排序頁面剛剛加載完成時(shí),newVal==oldVal==undefined 的情況
if(newVal==oldVal){
return;
}
$scope.num++;
})
}]);
</script>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
??當(dāng)頁面加載完成時(shí),$watch 函數(shù)將會(huì)首次執(zhí)行,這時(shí)的newVal 和oldVal 都為undefined 。
5. 解決ng-if 中ng-model 值無效的問題
??ng-if 與ng-show 的區(qū)別在于,前者將會(huì)移除DOM元素,而后者只是將元素的display 設(shè)為none 。
??與其他指令一樣,ng-if指令也會(huì)創(chuàng)建一個(gè)自己作用域,因此,如果在ng-if中添加了元素,并向元素屬性增加ng-model指令,那么ng-model指令對應(yīng)的作用域?qū)儆谧蛹壸饔糜?,并非控制器注入?code>$scope作用域?qū)ο蟆?/p>
<div ng-controller='myController'>
<div>
a的值:{{a}} <br>
b的值:{} <br>
</div>
<div>
普通方式: <input type="checkbox" ng-model='a' />
</div>
<div ng-if='!a'>
ngIf方式: <input type="checkbox" ng-model='$parent.b' />
</div>
</div>
<script type="text/javascript">
var app=angular.module('myapp',[]);
app.controller('myController',['$scope',function($scope){
$scope.a=false;
$scope.b=false;
}]);
</script>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
|