V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
rubyking
V2EX  ›  程序员

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

  •  
  •   rubyking · 2015-01-20 14:54:12 +08:00 · 13050 次点击
    这是一个创建于 3624 天前的主题,其中的信息可能已经有所发展或是发生改变。
    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   ·   实用小工具   ·   5386 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 05:45 · PVG 13:45 · LAX 21:45 · JFK 00:45
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.