您现在的位置:首页 >> 前端 >> 内容

Angularjs【监听数据的变化】和【如何修改数据】和【数据变化的传播】

时间:2016/5/9 9:18:51 点击:

  核心提示:一:监听数据的变化:由于编译仅仅在启动引导时执行一次,这意味着我们的link函数只会被调用一次,那么, 如果数据变化,在界面上将不会有任何反馈,即界面和数据将变得不同步了。这需要持续监听数据的变化。好...

一:监听数据的变化:

由于编译仅仅在启动引导时执行一次,这意味着我们的link函数只会被调用一次,那么, 如果数据变化,在界面上将不会有任何反馈,即界面和数据将变得不同步了。

这需要持续监听数据的变化。

好在AngularJS的scope对象可以使用$watch()方法,对建立在其上的变量的变化进行监听:

watch(watchExpression,listener,[objectEquality]);watch方法要求传入三个参数:

watchExpression - 要监听的表达式,比如:”sb”
listener - 变化发生时的回调函数,AngularJS将向这个函数传入新值和旧值
objectEquality - 如果监听表达式的值是一个对象,应当将这个参数置为true。
实例代码:
Html文件:


<script src="https://lib.sinaapp.com/js/angular.js/angular-1.2.19/angular.min.js"></script> 

js部分:

angular.module("ezstuff",[])
.directive("ezNamecard",function($rootScope){
    return {
        restrict : "E",
        template : "

", replace : true, link : function(scope,element,attrs){ element.append("

name :

") .append("

gender :

") .append("

age :

") //监听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,意图让其展开成这样:

name : gender : age :

在data-editor的指令实现中,为了用input中的值自动更新 sb变量中的值,我们需要在给input对象挂接上监听函数(示例中使用keyup事件), 在监听函数中实现对sb变量的修改。

最终的效果是,用户在界面上进行的操作,自动地同步到了我们的数据。这时,我们称, 已经建立了从界面到数据的单向绑定。

js部分:

angular.module("datdatest",[])
.directive("dataeditor ",function(){
    return {
        restrict : "E",
        template : "
    ", replace : true, link : function(scope,element,attrs){ //获得变量名称 var model = attrs.data; //展开HTML模板,使用field属性标记对应字段 element.append("
    • name :
    • ") .append("
      • gender :
      • ") .append("
        • age :
        • "); //监听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("
          "+cnt+"

          三:数据变化的传播

          数据绑定有两个方向:

          数据 → 界面:我们使用scope对象的watch()方法监听数据的变化,来更新界面。界面→数据:我们在界面的DOM对象上监听变化事件,来更新数据,并通过apply()方法传播变化。

          watch()每个scope对象都维护了一个私有的监听队列,每次当我们在scope上执行一次watch方法,就相当于 向这个监听队列里塞入一个监听函数。

          apply()为了捕捉对数据的修改,AngularJS要求开发者使用scope对象的apply方法对数据进行修改, $apply方法内部会自动地调用监听队列里的监听函数,比如:

          //方法1:直接修改sb对象. 不会自动触发监听函数
          scope.sb.name = ‘Tonny’;

          //方法2:使用scope的apply方法,在数据修改后会自动触发监听函数scope.apply(“sb.name = ‘Tonny’”);

          //方法3:直接修改sb对象,然后调用apply方法来传播变化。scope.sb.name=‘Tonny′;scope.apply(“”);
          在有些情况下,AngularJS会自动调用apply方法,比如在初次编译的时候。但无论哪种情况,希望你能了解,对数据的变化监听,总是需要通过apply方法的调用而被激活,如果 AngularJS没有获得一个机会来调用$apply,就需要你手工的调用它。

    Tags:AN NG GU UL 
    作者:网络 来源:qq_Dai的专栏