1. 页面元素的控制
1.1 调用element 方法控制DOM元素
使用Angular 框架开发应用时,尽量不要直接通过Javascript 代码直接操作DOM元素,也不要引入Jquery 来操作DOM元素,而是通过Angular内部的jQLite 来实现:
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('这是动态添加的方法!');
};
var html="<div ng-click='log()'>{{hello}}</div>";
//生成一个Jquery对象
var template=angular.element(html);
//对生成的Jquery对象进行编译
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 服务,目的是初始化相关的依赖,并对生成的Jquery对template进行编译,以便于调用append方法。
1.2 解决setTimeout 改变属性的无效
在Angular中,大部分操作之后的效果都由$apply 方法自动在页面中完成,如果直接调用非Angular中的方法或函数,例如setTimeout 方法,那么系统就不会调用$apply 方法,导致方法执行失败。
有两种方法可以解决:
- 在setTimeout方法中,将执行的函数或表达式包含在
$apply 方法中
setTimeout(function(){
scope.apply(function(){
$scope.tip=’欢迎来到Angular世界!’;
})
},1000)
- 直接调用与setTimeout方法对应的
$timeout 服务
$timeout(function(){
$scope.tip=’欢迎来到Angular世界!’;
},1000)
1.3 解决双大括号绑定元素时的闪烁问题
在Angular内部,可以向元素中添加ng-clock 属性来实现元素的隐藏效果:
<div ng-clock>{{message}}</div>
如果是绑定纯文字的内容,建议使用ng-bind 的方式,而非双大括号:
<div ng-bind="message"></div>
2. 使用ng-repeat 时的注意事项
2.1
- 如果有过滤器,调用
$index 并不能准确定位到对应的记录。
解决方案:使用其他的定位方式,例如元素的id等。
- 调用ng-repeat指令重新请求数据时,并不是在原来的DOM元素中更新数据,而是再次新建DOM元素。
解决方案:使用track by 排序ng-repeat中的数据:
user in users track by user.id
- 在通过ng-repeat指令生成的子元素中,如果通过父元素的scope对象更新数据时,不能直接更新遍历的数据源,而必须逐个更新。
2.2 正确理解ng-repeat指令中的scope继承关系
在调用ng-repeat 指令显示数据时,ng-repeat 在新建DOM元素时,也为每个新建的DOM元素创建了独立的scope作用域。
尽管如此,但它们的父级scope作用域是相同的,都是构建控制器时注入的$scope 对象,调用angular.element(domElement).scope 方法可以获取某个DOM元素所对应的作用域,通过某个DOM元素所对应的作用域又可以访问到他的父级作用域,从而修改绑定的数据源。
<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. 解决单击按钮事件中的冒泡现象
与在Javascript中一样,都可以使用stopPropagation() 方法,在Angular中:
$event.stopPropagation()
4. 释放多余的$watch 检测函数
在Angular中,当$watch 函数被调用时,将返回一个释放$watch 绑定的unbind 函数,因此,只需要再次调用这个$watch 函数机具款有释放其检测功能。
<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){
//排序页面刚刚加载完成时,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
当页面加载完成时,$watch 函数将会首次执行,这时的newVal 和oldVal 都为undefined 。
5. 解决ng-if 中ng-model 值无效的问题
ng-if 与ng-show 的区别在于,前者将会移除DOM元素,而后者只是将元素的display 设为none 。
与其他指令一样,ng-if指令也会创建一个自己作用域,因此,如果在ng-if中添加了元素,并向元素属性增加ng-model指令,那么ng-model指令对应的作用域属于子级作用域,并非控制器注入的$scope 作用域对象。
<div ng-controller='myController'>
<div>
a的值:{{a}} <br>
b的值:{{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
|