2014-06-26 39 views
1

这一问题与上一个问题,因此不再看了,因为它有一个upvoted答案进步的错误:Change jQuery Knob Min/Max value

下面的代码是一个用于jQuery旋钮插件的封装。我知道现有的角包装,但我用这个来进一步理解角框架。无论如何,所以我的问题是,当$ watch()检测到旋钮的最小值和最大值发生变化时,触发的变化事件会在角度内导致某种冲突,导致$ digest已在进行中。注释掉变化函数中的两行不会阻止错误,但会注释掉$(elem).trigger('change');线做。这打破了我最初的假设,即范围。$ apply()是原因。如果有人知道这里发生了什么,任何信息将不胜感激。谢谢。

App.directive('knobWidget', function() { 
    return { 
     scope: { 
      minbinding: "=minbinding", 
      minbindingprop: "@minbindingprop", 
      maxbinding: "=maxbinding", 
      maxbindingprop: "@maxbindingprop", 
      delta: "@delta" 
     }, 
     restrict: 'A', 
     require: 'ngModel', 
     link: function (scope, elem, attrs, ngModel) { 
      ngModel.$render = function() { 
       $(elem).val(ngModel.$viewValue) 
       $(elem).trigger("change"); 
      }; 
      $(elem).knob({ 
       min: 0, 
       max: 1, 
       value: ngModel.$viewValue, 
       change: function (changeVal) { 
        ngModel.$setViewValue(changeVal); 
        scope.$apply(); 
       } 
      }); 
      scope.$watch(function() { return scope.maxbinding[scope.maxbindingprop] }, function (newVal) {   
       $(elem).trigger('configure', { 'max': scope.maxbinding[scope.maxbindingprop] + parseInt(scope.delta) }); 
       $(elem).trigger('change');    
      }); 
      scope.$watch(function() { return scope.minbinding[scope.minbindingprop] }, function (newVal) {   
       $(elem).trigger('configure', { 'min': scope.minbinding[scope.minbindingprop] + parseInt(scope.delta) }); 
       $(elem).trigger('change');    
      }); 
     } 
    }; 
}); 
+0

我想通过将更改触发器包装在$ timeout中来解决此问题,但我仍然对理解原因感兴趣。我确信我不是唯一有这种麻烦的人。谢谢。 – AaronF

+1

使用$ timeout让当前的摘要循环在完成另一个摘要之前完成,我认为这是角度编程的常用做法。 –

+0

啊,这就是发生了什么......谢谢刘烨。 – AaronF

回答

0

不要使用$超时使用范围。$$阶段,而不是

if(!scope.$$phase){ 
    scope.$apply(); 
} 

这将防止循环,不使你的代码异步的。如果您目前处于摘要循环中,则无需调用

+0

请注意,以'$$'为前缀的属性应该被视为“私有”,这意味着它们不属于API的一部分,并且不打算用于Angular本身之外的其他用途(依赖于它们会增加代码在升级时崩溃的风险到更新版本的Angular)。 – Strille

+0

http://stackoverflow.com/a/23102223/3063787 – AaronF