$ value在更改值时未触发

时间:2015-03-27 06:30:40

标签: javascript jquery angularjs

我对在Angularjs中何时使用$ apply感到有点困惑,我的困惑来自以下示例。

这是我的设计:

1)我制作了一个自定义指令" profile-modal"它具有属性"可见","可见"属性存储" profileShow"决定是否显示弹出框的变量

2)在指令中,我双向绑定可见的attrible,因为外部作用域控制器将修改" profileShow"变量,同时指令将修改"可见"显示/隐藏框

的属性

3)当用户点击指定按钮时,控制器将修改" profileShow" vaiable,框会弹出

4)当用户关闭引导框时,on hidden函数将改变属性" visible"触发$ watch in指令关闭对话框。

这是代码

<profile-modal visible="profileShow"></profile-modal>
<button type="button" class="btn btn-primary btn-sm" ng-click="addConfProfile()">
   <span class="glyphicon glyphicon-plus"></span> Add Profile
</button>

    define(['testConfig','bootstrap-dialog'],function(testConfig, BootstrapDialog){
    testConfig
        .controller('apConfCtrl', function($scope){
            $scope.profileShow = false;
            $scope.addConfProfile = function(){
                $scope.profileShow = !$scope.profileShow;
            };
        })
        .directive('profileModal',function(){
            return {
                restrict: 'E',
                templateUrl: 'templates/profile_add_dialog.html',
                replace: true,//replace the original profile modal dom
                scope:{
                    visible: '=',
                },
                link: function(scope, elm, attr){
                    //set modal title
                    scope.profileTitle = "Add Profile";
                    scope.$watch('visible', function(n,o){
                        console.log(n);
                        console.log(o);
                        if (n){
                            $(elm).modal('show');
                        }
                        else{
                            $(elm).modal('hide');
                        }
                    });

                    $(elm).on('hidden.bs.modal', function(){
                        scope.visible = false;
                        scope.$apply(); // >>Why this is necessary??
                        //console.log(scope.visible);
                    });

                }
            };
        });
});

但实施后,我面临以下问题,第一次点击按钮,一切按预期工作,弹出框,然后关闭框。在第二次我尝试打开盒子,没有任何弹出窗口......然后我再次尝试点击,再次弹出窗口。

然后我弄清楚主要的问题是on隐藏动作不会触发$ watch函数来改变属性&#34; visible&#34;,但令人惊讶的部分是当我尝试添加范围时。$ apply更改属性变量后,它可以工作!我只是想知道为什么我必须这样做,Angularjs想要帮助监控变量&#34; visible&#34;没有打电话给$ apply?

感谢任何帮助

2 个答案:

答案 0 :(得分:3)

Angular依赖于一个名为&#34;摘要周期&#34;拿起任何变化。触发摘要周期的事情是调用$scope.$digest()$scope.$apply()

对于大多数内置的Angular指令,它们已经为您触发了摘要周期。例如,在监视表达式发生变化时执行的监听侦听器功能在检测到更改的摘要周期内执行。

然而,对于任何不属于Angular的东西,例如发生jQuery事件,你需要&#34;告诉&#34;关于它的角度。这意味着自己调用$scope.$apply()

答案 1 :(得分:0)

还建议您在$scope的子对象内定义布尔值,数字或字符串属性(在您的情况下为'profileShow'),而不是直接使它们成为$scope的属性。这种方法的原因是bool,数字和字符串按值传递,而数组和对象通过引用传递。因此,即使您的属性发生更改,您也必须手动调用$digest方法,angular将不会为您调用$apply()周期。