如何在angularJS中等到$ compile结束

时间:2015-07-23 13:39:49

标签: javascript angularjs

我正在加载模板,然后使用$compile服务针对我的范围进行编译。

var template = "<div> .. {{someCompilingStuff}} ..</div>";
var compiled = $compile(template)(cellScope);

然后在弹出框中使用它

cellElement.popover({
    html: true,
    placement: "bottom",
    trigger: "manual",
    content: compiled
});

我的模板非常复杂,可能需要一些时间来编译。

如何在弹出窗口中使用角色之前确保角度已完成编译?

编辑:我在创建弹出框之前尝试将角度强制设为$apply(),它确实有效,但会生成javascript错误,这对我来说是不可接受的。

7 个答案:

答案 0 :(得分:16)

$compile允许您使用所谓的克隆附加功能,该功能允许您将元素附加到文档。以下是您可以使用的示例:

var template = "<div> .. {{someCompilingStuff}} ..</div>";
var compiled = $compile(template)(cellScope, function (clonedElement) {
  cellElement.popover({
    html: true,
    placement: "bottom",
    trigger: "manual",
    content: clonedElement
  });
});

Reference to Angular documentation about $compile usage

答案 1 :(得分:2)

在这些情况下,您可能希望使用$timeout来解决问题。

这样的事情:

var template = "<div> .. {{someCompilingStuff}} ..</div>";
var compiled = $compile(template)(cellScope);
cellElement.popover({
   html: true,
   placement: "bottom",
   trigger: "manual",
   content: compiled
 });

$timeout(function(){
    cellElement.popover("show");
}, 0);

以下是我为您创建的示例JSFIDDLE。看看我如何展示&amp;使用$timeout隐藏弹窗窗口。

答案 2 :(得分:0)

即使在编译/链接功能完全呈现模板时可以获得通知,您仍然无法确定浏览器是否完成了对页面布局的更改作为响应。您可以通过在触发弹出窗口之前使用$timeoutsetTimeout)引入一个小延迟来解决问题。通过阅读is there a post render callback for Angular JS directive?上的答案,我认为这可以解决您的问题。

答案 3 :(得分:0)

我将提供一个非代码答案(所以你可以多挖一点并了解原因 - 加上我在这个时候感到很懒):

我建议将事件委托与另一个父HTML元素一起用作委托,您可以在其上调用popover方法。只需在任何[parent]元素上包含一个class =“popover”,然后在其中编译一个模板。您可以在该父元素上执行/调用popover方法。但是,我不完全确定你不需要子元素(来自模板)因为我不知道插件。不过,我会尝试除了超时之外的任何事情。

我希望这个答案(虽然可能不正确)会促成作者的创造性解决方案(产生干净,可靠的代码)。

答案 4 :(得分:0)

作为建议,您可以创建一个编译器服务,其中注入$ compile并创建一个参数接受html和范围的方法。

在该方法中使用$ deferred并从您的控制器调用该方法并解析将给您一个回调,这是一个完成编译的承诺。

请告诉我,如果它适用于您,我将为您提供代码示例。

答案 5 :(得分:-1)

    var template = "<div> .. {{someCompilingStuff}} ..</div>";

cellElement.popover({
  html: true,
  placement: "bottom",
  trigger: "manual",
  content: function () {
    var html = "";
    $compile(template)(cellScope, function (clonedElement) {
      html = clonedElement;
    });
    return html;
  }

});

答案 6 :(得分:-2)

我会尝试将模板的编译包装在一个返回promise的函数中。

像这样:

function compile () {
  var deferred = $q.defer();

  /** simulate something sloooow (remove the setTimeout in your implementation) **/
  setTimeout(function () {
    deferred.resolve($compile('content')(scope));
  }, 2000);

  return deferred.promise;
}

// and then ...
compile().then(function (content) {
  element.popover({
    content: content
  });
});

'naive' jsbin&amp;&amp; jsfiddle (modified @Amir's)

我无法保证它会针对您的具体情况而工作,但值得一试。