angularjs中有两个非常重要的概念,一个就是本章要介绍的数据双向绑定,另一个则是从后端延伸过来的依赖注入。那么何为数据双向绑定呢?顾名思义,即元数据(model)和视图(view)展示的数据存在绑定关系,当元数据中的信息发生变化时,视图中的数据会实时变化,反之亦然。
首先我们来看一个视图数据变更映射到元数据中的例子:
首先在controller中定义一个变量data,然后在页面上定义的输入框绑定这个变量,接下来在输入框中改变这个变量的值,最后通过在controller中定义的定时器来查看变量是否随着视图中的变更而变化。
在c2.js中定义变量以及定时器:
/**
* Created by 李庆 on 2016/10/6.
*/
define(["jquery","../../../framework/service/httpService"],function($,httpService){
var c2Controller = ["$scope","maskService",function($scope,maskService){
$scope.test = function(){
console.log("enter controller");
};
$scope.getData = function(){
maskService.show("get data");
$.ajax({
"type":"GET",
"contentType":"application/json;charset=UTF-8",
//修改前为"url":"mock/test.json",
"url":httpService.getUrl("GET","/nova/test.json"),
"success":function(data){
console.log(JSON.stringify(data));
setTimeout(function(){
maskService.hide();
},6000);
},
"error":function(data){
console.log("error");
}
});
};
$scope.data = "";
setInterval(show,1000);
function show(){
console.log("data is "+ $scope.data);
}
}];
return c2Controller;
});
在c2.html中定义输入框并绑定controller中定义的变量:
然后我们来看一下页面:
在没有改变输入框的值之前,定时器打印的data变量值一直为空,当在输入框中输入1后,定时器打印的data变量值变为1,这表示视图数据变更映射到了元数据。
上面的例子中,controller中定义的变量data在页面上定义的输入框中正常显示,即为元数据映射到了视图,接下来我们看一个元数据映射到视图的特例:
我们在上例的定时器中变更变量data的值,查看输入框的值是否同步变更。
在c2.js中定义变量以及定时器:
/**
* Created by 李庆 on 2016/10/6.
*/
define(["jquery","../../../framework/service/httpService"],function($,httpService){
var c2Controller = ["$scope","maskService",function($scope,maskService){
$scope.test = function(){
console.log("enter controller");
};
$scope.getData = function(){
maskService.show("get data");
$.ajax({
"type":"GET",
"contentType":"application/json;charset=UTF-8",
//修改前为"url":"mock/test.json",
"url":httpService.getUrl("GET","/nova/test.json"),
"success":function(data){
console.log(JSON.stringify(data));
setTimeout(function(){
maskService.hide();
},6000);
},
"error":function(data){
console.log("error");
}
});
};
$scope.data = 0;
console.log(new Date());
setInterval(show,1000);
function show(){
console.log(new Date());
$scope.data++;
console.log("data is "+ $scope.data);
}
}];
return c2Controller;
});
c2.html内容不变。
然后我们来看一下页面:
可以看到控制台打印的变量一直在变更,但是输入框的值一直保持不变。为什么数据双向绑定在这里失效了呢?这是由于我们在controller中自定义的定时器变更变量的行为angularjs并不感知(类似的行为还包括ajax的异步请求),此时就需要靠我们来主动触发数据双向绑定:
在c2.js中定义变量以及定时器,并主动触发数据双向绑定:
/**
* Created by 李庆 on 2016/10/6.
*/
define(["jquery","../../../framework/service/httpService"],function($,httpService){
var c2Controller = ["$scope","maskService",function($scope,maskService){
$scope.test = function(){
console.log("enter controller");
};
$scope.getData = function(){
maskService.show("get data");
$.ajax({
"type":"GET",
"contentType":"application/json;charset=UTF-8",
//修改前为"url":"mock/test.json",
"url":httpService.getUrl("GET","/nova/test.json"),
"success":function(data){
console.log(JSON.stringify(data));
setTimeout(function(){
maskService.hide();
},6000);
},
"error":function(data){
console.log("error");
}
});
};
$scope.data = 0;
console.log(new Date());
setInterval(show,1000);
function show(){
console.log(new Date());
$scope.$apply(function($scope){
$scope.data++;
});
console.log("data is "+ $scope.data);
}
}];
return c2Controller;
});
c2.html保持不变。
再看一下此时的页面:
此时控制台打印的变量一直在变更,且输入框的值也保持同步变更。
注意,只有在以下几种情况下才会触发数据双向绑定:
ng标签触发的事件
angularjs服务触发的数据变更(如$inerval,而不是原生的setInterval函数)
主动执行$digest()或$apply()