angular之$apply尝试

angular开辟历程当中碰到的$apply题目

由于一直在项目上并吗运用过angular举行开辟,现在会碰到一些比较弱智的题目,所以每次碰到耗时较多的题目都总结一下。

$apply题目

接到一个类似于dropdown如许的需求,点击按钮下拉挑选展现,而它的封闭有3中场景。

  1. 现在处于睁开状况,再次点击按钮,下拉隐蔽。

  2. 点击内里的任一前提,下拉隐蔽。

  3. 点击空白处,下拉隐蔽。

置信如许的运用场景肯定不生疏,由于他经常出现。

一开始的时刻想象了一下jquery何等优美,完成起来何等简朴,实在angular也很轻易。

思绪剖析:

外层设置一个状况值,经由历程增加ngClass掌握下拉是不是显现。想象都是优美的,也经由历程测试如许没有题目。

完成历程:

1.html誊写

<div class="content" ng-class="{'open': vm.open}">
    <span class="show" ng-click="vm.toggle()">cilic me!</span>
    <div class="list">
        <ul>
            <li class="item" ng-repeat="item in list" ng-click="vm.itemClick();">{{item.title}}</li>
        </ul>
    </div>
</div>

2.css代码掌握

.content .list{
    display: block;
}  
.content.open .list{
    display: block;
}  

3.mock静态数据

vm.list = [
    {title: '下拉选项1'},
    {title: '下拉选项2'},
    {title: '下拉选项3'},
    {title: '下拉选项4'},
    {title: '下拉选项5'}
];

4.点击按钮掌握显现隐蔽,我只需要掌握open状况为true或false即可。

// 设置初始状况为不显现
vm.open = false;
// 显现,封闭浮层
vm.toggle = function() {
    vm.open = !vm.open;
};  

5.点击任一下拉挑选,隐蔽。

vm.itemClick = function() {
    vm.ticketOpen = false;
};

6.点击空白处,隐蔽。

$document.off('click').on('click', function() {
    vm.open = false;
});

看到如许的代码,你以为有题目吗?横竖我当时以为本身肯定是对的,但调试效果就是不见效,下拉怎样都不会隐蔽。
经由历程断点调试,页面输出open的值,发明js中的open确切已发作转变,然则页面的值确没有转变,然后联想到双向数据绑定失效。

谁决议什么事宜进入angular context,而哪些又不进入呢?$apply!

这里声明一点ng-click不需要零丁去做处置惩罚是由于angular已做了,因而点击带有ng-click的元素时,事宜就会被封装到一个$apply挪用。

所以上面的题目也不言而喻,是由于没有挪用$apply,事宜没有进入angular context, $digest轮回永久没有实行。
so将code修为:

$document.off('click').on('click', function() {
    vm.open = false;
    $scope.$apply();
});

如许一测,立马有用了。
$apply是$scope的一个函数,挪用它会强迫一次$digest轮回.
然后看到网上有人说有种更好用的方法,尝试了一下确切有用:

$document.off('click').on('click', function() {
    $scope.$apply(function () {
        vm.open = false;
    });
});

解释为:

What’s the difference?
The difference is that in the first version, we are updating the values outside the angular context so if that throws an error, Angular will never know.
Obviously in this tiny toy example it won’t make much difference,
but imagine that we have an alert box to show errors to our users and we have a 3rd party library that does a network call and it fails.
If we don’t wrap it inside an $apply, Angular will never know about the failure and the alert box won’t be there.

参考文章地点: http://angular-tips.com/blog/…

    原文作者:silence
    原文地址: https://segmentfault.com/a/1190000005902935
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞