标签:
由于编译仅仅在启动引导时执行一次,这意味着我们的link函数只会被调用一次,那么, 如果数据变化,在界面上将不会有任何反馈,即界面和数据将变得不同步了。
这需要持续监听数据的变化。
好在AngularJS的scope对象可以使用$watch()方法,对建立在其上的变量的变化进行监听:
watchExpression - 要监听的表达式,比如:”sb”
listener - 变化发生时的回调函数,AngularJS将向这个函数传入新值和旧值
objectEquality - 如果监听表达式的值是一个对象,应当将这个参数置为true。
实例代码:
Html文件:
<html>
<head>
<script src="http://lib.sinaapp.com/js/angular.js/angular-1.2.19/angular.min.js"></script>
</head>
<body ng-app="ezstuff" ng-init="sb = {name:‘somebody‘,gender:‘male‘,age:28}">
<ez-namecard data="sb"></ez-namecard>
</body>
</html>
js部分:
angular.module("ezstuff",[])
.directive("ezNamecard",function($rootScope){
return {
restrict : "E",
template : "<div class=‘namecard‘>",
replace : true,
link : function(scope,element,attrs){
element.append("<div>name : <span class=‘name‘></span></div>")
.append("<div>gender : <span field=‘gender‘></span></div>")
.append("<div>age : <span field=‘age‘></span></div>")
//监听sb变量的变化,并在变化时更新DOM
scope.$watch(attrs.data,function(nv,ov){
var fields = element.find("span");
fields[0].textContent = nv.name;
fields[1].textContent = nv.gender;
fields[2].textContent = nv.age;
},true);
//验证代码,1秒改变1次age的值
setInterval(function(){
scope.$apply("sb.age=sb.age+1;")
},1000);
}
};
});
为了看到效果,稍微加点样式
CSS部分:
.namecard{
border : 1px solid #000;
border-radius : 10px;
padding:10px;
width:300px;
background:#f0f0f0;
}
一旦在指令的实现代码中可以访问数据模型,那么使用声明式模板实现数据 修改也非常简单了。
我们定义一个新的指令:data-editor,意图让其展开成这样:
在data-editor的指令实现中,为了用input中的值自动更新 sb变量中的值,我们需要在给input对象挂接上监听函数(示例中使用keyup事件), 在监听函数中实现对sb变量的修改。
最终的效果是,用户在界面上进行的操作,自动地同步到了我们的数据。这时,我们称, 已经建立了从界面到数据的单向绑定。
html部分:
<html>
<head>
<script src="http://lib.sinaapp.com/js/angular.js/angular-1.2.19/angular.min.js"></script>
</head>
<body ng-app="datdatest" ng-init="sb = {name:‘somebody‘,gender:‘male‘,age:28}">
<!-- 下面两个指令都绑定到变量sb上-->
<data-editor data="sb"></data-editor>
<div ez-logger data="sb"></div></body>
</html>
js部分:
angular.module("datdatest",[])
.directive("dataeditor ",function(){
return {
restrict : "E",
template : "<ul class=‘nceditor‘></ul>",
replace : true,
link : function(scope,element,attrs){
//获得变量名称
var model = attrs.data;
//展开HTML模板,使用field属性标记对应字段
element.append("<li>name : <input type=‘text‘ field=‘name‘></li>")
.append("<li>gender : <input type=‘text‘ field=‘gender‘></li>")
.append("<li>age : <input type=‘text‘ field=‘age‘></li>");
//监听DOM事件,变化时修改变量值
element.find("input").on("keyup",function(ev){
var field = ev.target.getAttribute("field");
scope[model][field] = ev.target.value;
//将对scope的修改进行传播
scope.$apply("");
});
}
};
})
.directive("ezLogger",function(){
return {
restrict : "A",
link : function(scope,element,attrs){
var model = attrs.data;
scope.$watch(model,function(nv){
var cnt = JSON.stringify(nv,null," ");
element.html("<pre>"+cnt+"</pre ");
},true);
}
};
});
三:数据变化的传播
数据绑定有两个方向:
数据 → 界面:我们使用scope对象的
//方法1:直接修改sb对象. 不会自动触发监听函数
scope.sb.name = ‘Tonny’;
//方法2:使用scope的
//方法3:直接修改sb对象,然后调用
在有些情况下,AngularJS会自动调用
Angularjs【监听数据的变化】和【如何修改数据】和【数据变化的传播】
标签:
原文地址:http://blog.csdn.net/qq_dai/article/details/51347584