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
num
和 bar
都没有变。印象中,这种传值方式应该符合 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 的过程:
点击了页码,
ng-click
的绑定使得 directive 中的changeCurrentPageNo()
这个方法触发触发后,directive 的
scope.currentPageNo
会更新,但这一步并不会让 parent 更新然后你调用了来自父级的方法
changePageNo()
,这时候父级只知道你调用了changePageNo
这个方法,然而并不知道currentPageNo
已经在 directive 中改变。确切一点儿说,你改的是值本身,而不是改了引用。请参考上面例子中的bar
情况。所以,这时候只有 directive 内部知道,而父级不知道这时候,"digest loop" 得到了第一步触发,启用了
$watch
(当然也会触发 dirty 检查)。但由于父级上的值并没有改变,你在console.log
的时候,还是原来的值。既然也没监测到变化,当然,页面上的数据也是不会更新的directive 执行完毕,触发
$apply
,这时候currentPageNo
终于得到了更新,父级的也更新了,但这个发生的太晚,你已经看不到了。不过,你在下一次调用的changePageNo
的时候,console log 才会输出这一次的值,然后又把它更新到了一个新的值
不知道这样分析是否正确。
这篇关于javascript - AngularJS1 指令隔离作用域中的双向绑定模型数据不能及时更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!