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我知道这样说可能不够确切。。
这个应该是你想要的效果吧?其实解决方式很简单,在
index.html
里面把$scope.currentPageNo = 1
改成$scope.current = { pageNo: 1 }
当然,相应地:
另外 directive 定义部分也要改:
读完 AngularJS 的官方 wiki 就明白了:https://github.com/angular/an...
讲道理,楼上说到的,用
$watch
或者$timeout
之类的应该也行,但恐怕不是最好的写法。我个人觉得,这是 JavaScript 中传值方式导致的。。你可以考虑下,JS 中这段代码输出的是啥:
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 才会输出这一次的值,然后又把它更新到了一个新的值不知道这样分析是否正确。
$timeout(function(){
}, 0)
原因在于调用第三方方法,angular不能捕捉到变化
试试$watch这个函数,手动刷新
在link里面注册$watch
调用外部方法后,要数据同步,需要手工执行 $scope.$digest(). 或者 将执行部分放在 $scope.$apply()方法内 来使Angular触发脏检查.