在$ compile之后调用$ apply时出现$ digest错误

时间:2013-11-19 21:53:53

标签: angularjs

我正在构建一个指令来处理翻转工具提示。我已经将HoverIntent与Zurb Foundations Tooltip类集成在一起。有用! 然而 ...我得到了我们太熟悉的可怕Error: $digest already in progress错误。这仅在buildFromTemplate函数第一次执行时发生。理想情况下,我想从我的代码中删除scope.$apply(),但是我不确定如何在保持正常功能的同时做到这一点。

使用类型 使用此指令有三种不同的方法,但问题只发生在用法3上

# Usage 1:
%a(rollover title="Add New")

# Usage 2:
%a(rollover rollover-element"#some-element-id")
%div(id="some-element-id")
  Add New

# Usage 3:
%a(rollover rollover-template="rollover1.html")
# FILE 'rollover1.html':
%div
  {{data.name}}

守则(咖啡脚本):

angular.module('app.common').directive 'rollover', ['$http', '$compile', '$templateCache', ($http, $compile, $templateCache) ->
  restrict: 'A'
  scope: true
  replace: false
  template: ''

  link: (scope, element, attrs) ->
    selector = ''

    buildFromTemplate = (html) ->
      compiled = $compile( angular.element("<div>"+html+"</div>") )(scope)

      # ERROR Occurs Here:
      scope.$apply()

      # Without the scope.$apply, compiled.html() still contains unparsed {{variables}}
      element.attr('title', compiled.html())
      selector = 'tooltip' + Math.random().toString(36).substring(7)
      element.attr('data-tooltip','').attr('data-selector',selector).trigger('mouseenter')

    showOrCreate = ->
      # Build Appropriately
      if selector == '' and typeof attrs.rolloverTemplate == "string" and attrs.rolloverTemplate != ""
        template = $templateCache.get(attrs.rolloverTemplate)
        if !template
          $http.get(attrs.rolloverTemplate, {cache: $templateCache}).then (content) ->
            $templateCache.put(attrs.rolloverTemplate, content.data)
            buildFromTemplate(content.data)
        else
          buildFromTemplate(template)
      else
        if selector == ''
          if typeof attrs.rolloverElement == "string" and attrs.rolloverElement != ""
            element.attr('title', $(attrs.rolloverElement).html())
          selector = 'tooltip' + Math.random().toString(36).substring(7)

        element.attr('data-tooltip','').attr('data-selector',selector).trigger('mouseenter')

    hide = ->
      element.removeAttr('data-tooltip','').removeAttr('data-selector')
      $(".tooltip[data-selector="+selector+"]").hide()

    element.hoverIntent
      over: showOrCreate
      out: hide
      interval: 250
]

非常感谢任何帮助/想法。谢谢!

1 个答案:

答案 0 :(得分:2)

如果这是您在scope.$apply中使用buildFromTemplate的唯一原因,则可以使用Angular的$interpolate service进行插值

angular.module('app.common').directive 'rollover', ['$http', '$compile', '$templateCache', '$interpolate', ($http, $compile, $templateCache, $interpolate) ->
  restrict: 'A'
  scope: true
  replace: false
  template: ''

  link: (scope, element, attrs) ->
    selector = ''

    buildFromTemplate = (html) ->
      compiled = $interpolate(html)(scope)

      element.attr('title', compiled)
      selector = 'tooltip' + Math.random().toString(36).substring(7)
      element.attr('data-tooltip','').attr('data-selector',selector).trigger('mouseenter')