gpt4 book ai didi

javascript - 模板总是使用指令中的旧范围值进行编译

转载 作者:塔克拉玛干 更新时间:2023-11-02 21:31:33 26 4
gpt4 key购买 nike

我有一个指令是这样工作的:

http://jsfiddle.net/smithkl42/cwrgLd0L/23/

App.directive('prettify', ['$compile', function ($compile) {
var templateFn;
return {
restrict: 'E',
scope: {
target: '='
},
link: function (scope, element, attrs) {
if (!templateFn) {
var template = element.html();
templateFn = $compile(template);
}
scope.$watch('target', function (newVal, oldVal) {
var compiled = templateFn(scope);
element.html('');
element.append(compiled);
var html = element.html();
var prettified = prettyPrintOne(html);
element.html(prettified);
}, true);
}
};
}]);

问题是,当我编译模板时,它总是使用target 属性的old 值进行编译。所以它开始显示这个,即,它表现得好像没有什么可以替换:

enter image description here

然后,如果我向该属性添加一个字符,它会显示这个,即 scope.organization.message 属性的 previous 值:

enter image description here

调试显示范围指令的 target 属性中的值在编译时是正确的。

我做错了什么? $compile 返回的模板函数是否有一些查看旧作用域值的内容?或者……?

(另请参阅导致此问题的问题:Using $compile in a directive triggers AngularJS infinite digest error。)

最佳答案

首先,您的 templateFn变量的范围在工厂级别,但它在实例级别填充。这意味着您第一次使用该指令时,它将使用该元素的指令进行填充,之后的每次使用也将使用相同的模板,即使它实际上有不同的模板。

看似延迟绑定(bind)问题的原因与摘要周期以及 Angular 如何管理对 DOM 的更改有关。在处理范围更改时,范围观察器将在对 DOM 进行任何更改之前全部处理。这样,所有 DOM 更改都被合并到一个批处理中(至少对于该周期),因此您不会一次进行多个更新,从而可能导致多次回流。所以,当你调用 element.html() ,您这样做是在 DOM 尚未更新以反射(reflect)作用域中更改的值的时候。

在这种特殊情况下,您还需要做一些额外的工作 - 调用 templateFn将为您提供一个包含所需内容的 jQuery(或 jQLite)对象 - 无需将其添加到 DOM,然后再将其取出,您只需调用 html() 即可。直接反对它。

所有的逻辑都可以像这样合并(并正确工作):

setTimeout(function () {
var compiled = templateFn(scope).html();
var prettified = prettyPrintOne(compiled);
element.html(prettified);
}, 0);

将所有内容包装在 setTimeout 中强制在摘要周期完成后评估逻辑。

但是,一般来说,该指令的实现有点笨拙:

  • 如果每次使用都需要 HTML 模板(例如 <pre><code> 标签),则应通过 template 将其包含在指令本身中。或 templateUrl属性,而不是期望消费者知道它是必需的
  • 你或许可以在不使用 $compile 的情况下实现它- 你可以把 prettyPrintOne 的输出在作用域上,并在 template 中指定的模板中绑定(bind)到它或 templateUrl属性,或者您可以使用 jQuery 获取对将成为容器的任何元素的引用(也就是说,如果它不是顶级元素)并使用 html()设置其内容。
  • 如果您确实需要允许在指令中定义其他模板化 HTML 内容,请查看 transclude directive guide 中定义的选项.

关于javascript - 模板总是使用指令中的旧范围值进行编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27511269/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com