Angularjs 中数据双向绑定是怎么实现的? 原理是什么? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
rubyking
V2EX    程序员

Angularjs 中数据双向绑定是怎么实现的? 原理是什么?

  •  
  •   rubyking 2015-01-20 14:54:12 +08:00 13389 次点击
    这是一个创建于 3967 天前的主题,其中的信息可能已经有所发展或是发生改变。
    Angularjs中是数据双向绑定非常强大,于是就想知道他是怎么实现的(原理),哪位男神知道告知一二,小弟在此感谢,最好给个例子~
    16 条回复    2015-01-20 23:19:45 +08:00
    yakczh
        1
    yakczh  
       2015-01-20 14:57:57 +08:00
    我也想知道
    tomwan
        2
    tomwan  
       2015-01-20 15:04:42 +08:00
    最简单的说法,50ms为一个心跳,去判断一个controller里所有对象的变化,如果有变化,那么更新相关的元素
    rubyking
        3
    rubyking  
    OP
       2015-01-20 15:06:25 +08:00
    @tomwan 男神能举个例子吗?
    lujiajing1126
        5
    lujiajing1126  
       2015-01-20 15:18:58 +08:00
    之前用artTemplate的时候,直接替换整个html会闪一下,所以自己搞了个数据绑定
    主要思路我觉得就是在dom的属性上绑一些model的字段,如果model有变化,就去改变相应的model(整个很好做),然后更新dom。。
    比如说
    <div>{{person.name}}</div>
    会被渲染成
    <div data-binding="person.name">{{person.name}}</div>
    那么如果person.name变化了,自然能够通过data-binding整个属性去改变div的值
    反向的话,如果model更新,我觉得应该是事件触发的,比如说自带就有change,blur这些
    我觉得关键是需要non-logic的模板引擎,否则在模板里加了逻辑。。整个就跪了,因为另一个逻辑分支的内容不会被渲染到dom里面,从而你如果model更新换了逻辑分支的话那就没办法了
    {{if a}}
    <div>{{person.name}}</div>
    {{else}}
    <div>{{person.age}}</div>
    那么条件a变了,你也没法从age切到name
    shibo501c
        6
    shibo501c  
       2015-01-20 15:48:41 +08:00
    解释的话,网上能搜到很多,要想自己实现一下的话,这里有本书可以看,作者给的免费版本可以实现scope的逻辑,还是挺好的
    http://teropa.info/build-your-own-angular
    rannnn
        7
    rannnn  
       2015-01-20 15:53:47 +08:00 via iPhone
    scope变量是getter和setter 更新会在内部保留旧值

    然后绑定了keydown之类event 会触发$digest 遍历相关scope变量 触发$watch中的回调

    $digest会重复运行直到变量不再改变
    rannnn
        8
    rannnn  
       2015-01-20 15:56:57 +08:00 via iPhone
    不过angular hard code 了$digest连续运行10次就会直接exception
    datou552211
        9
    datou552211  
       2015-01-20 17:02:39 +08:00
    脏值检测
    rubyking
        10
    rubyking  
    OP
       2015-01-20 18:10:06 +08:00
    rubyking
        11
    rubyking  
    OP
       2015-01-20 18:12:48 +08:00
    @lujiajing1126 具体的解决办法呢
    rubyking
        12
    rubyking  
    OP
       2015-01-20 18:15:08 +08:00
    @rannnn 要是不是通过触发keydown之类event事件实现的呢? 比如某一个attribute属性发生了改变
    rubyking
        13
    rubyking  
    OP
       2015-01-20 18:15:47 +08:00
    @datou552211 @rannnn 需要自己实现一个
    rannnn
        14
    rannnn  
       2015-01-20 18:40:42 +08:00
    @rubyking
    angular会 parse attribute里的 express 比如attr="var1 + var2"
    就会watch var1和var2这两个scope variable,当运行$digest的时候检测到这两个变量变化了就会重新计算这个expression然后再触发相应的callback

    自己实现略麻烦,首先你还得写个parser(其实也不是很麻烦用esprima就好了)
    lujiajing1126
        15
    lujiajing1126  
       2015-01-20 18:46:14 +08:00
    @rubyking 我只是自己随便想的,满足自己的webapp的需求而已
    要做到很好的话还是参考angular的做法
    有一本书叫做build your own angular
    kimmykuang
        16
    kimmykuang  
       2015-01-20 23:19:45 +08:00
    angularjs的数据更新是基于dirty check的,至于什么时候去做check,你需要去看下一个叫$digest的东西,比如$scope里的东西变化了就会开始$digest,所以说“angularjs的数据双向绑定是依靠$scope实现的”也应该不是错误的。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5785 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 02:14 PVG 10:14 LAX 18:14 JFK 21:14
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86