javascript - AngularJS1 指令隔离作用域中的双向绑定模型数据不能及时更新

查看:136
本文介绍了javascript - AngularJS1 指令隔离作用域中的双向绑定模型数据不能及时更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

我使用 AngularJS 1.5.0 和 bootstrap 写了一个简单的分页指令,完整代码在这里:https://github.com/clearbug/c...
当分页的页码改变时,我调用了外部的方法:https://github.com/clearbug/c...
外部方法:https://github.com/clearbug/c...
但是不明白为啥指令里面 $scope.currentPageNo 已经更新了,但外面还是旧值,请问我在调用外部方法之前怎么让外部的值及时更新呢?

解决方案

这个应该是你想要的效果吧?其实解决方式很简单,在 index.html 里面把 $scope.currentPageNo = 1 改成 $scope.current = { pageNo: 1 }

当然,相应地:

$scope.toSearch = function(){
    console.log('To search ' + $scope.current.pageNo);
};

<div simple-pagination total-items="pager.totalItems" items-per-page="pager.itemsPerPage" max-items-num="pager.maxItemsNum" current="current" change-page-no="toSearch()"></div>

另外 directive 定义部分也要改:

scope: {
    totalItems: '=totalItems',
    itemsPerPage: '=itemsPerPage',
    maxItemsNum: '=maxItemsNum',
    current: '=current',
    changePageNo: '&changePageNo'
},

读完 AngularJS 的官方 wiki 就明白了:https://github.com/angular/an...

讲道理,楼上说到的,用 $watch 或者 $timeout 之类的应该也行,但恐怕不是最好的写法。


我个人觉得,这是 JavaScript 中传值方式导致的。。你可以考虑下,JS 中这段代码输出的是啥:

function update(a, b, c)
{
  a = a * 2;
  b.value = 2;
  c = {value: 2};
}

var num = 10;
var foo = {value: 1};
var bar = {value: 1};

update(num, foo, bar);

console.log(num);
console.log(foo.value);    
console.log(bar.value);

//output: 
// 10
// 2
// 1

numbar 都没有变。印象中,这种传值方式应该符合 pass by sharing: https://en.wikipedia.org/wiki...
不过我一直的理解是:primitive value 是 pass by value的,而 Object 就是 pass by reference我知道这样说可能不够确切。。

这里的 update 可以近似的理解为 AngularJS 中的 $scope.$apply(),是由 $watch 检测到 $dirty 的情况下触发的。foo.value 相当于我的写法里面的 current.pageNo,当然这个 current$scope 上的一个属性。num 相当于你的写法里面的 $scope.currentPageNo

所以这时候,我们需要的是直接把 current 这个 Object 按照引用(Pass by reference)的方式传进来,而不是把 Object 里面的某一个属性按照值传递(Pass by value)的方式传进来。


试着帮你分析一下,从点击到输出 console log 的过程:

  1. 点击了页码,ng-click 的绑定使得 directive 中的 changeCurrentPageNo() 这个方法触发

  2. 触发后,directive 的 scope.currentPageNo 会更新,但这一步并不会让 parent 更新

  3. 然后你调用了来自父级的方法 changePageNo(),这时候父级只知道你调用了 changePageNo 这个方法,然而并不知道 currentPageNo 已经在 directive 中改变。确切一点儿说,你改的是值本身,而不是改了引用。请参考上面例子中的 bar 情况。所以,这时候只有 directive 内部知道,而父级不知道

  4. 这时候,"digest loop" 得到了第一步触发,启用了 $watch(当然也会触发 dirty 检查)。但由于父级上的值并没有改变,你在 console.log 的时候,还是原来的值。既然也没监测到变化,当然,页面上的数据也是不会更新的

  5. directive 执行完毕,触发 $apply,这时候 currentPageNo 终于得到了更新,父级的也更新了,但这个发生的太晚,你已经看不到了。不过,你在下一次调用的 changePageNo 的时候,console log 才会输出这一次的值,然后又把它更新到了一个新的值

不知道这样分析是否正确。

这篇关于javascript - AngularJS1 指令隔离作用域中的双向绑定模型数据不能及时更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆