Angular中指令中的$compile和compile函数之间有什么区别?

4
我正在尝试使用我构建的仓库检索指令的模板,该仓库返回一个解析为模板内容的Promise。
在指令中使用compile函数和在link函数中使用$compile服务有何区别?
编译函数。
compile: function (element, attrs) {
    templateRepository.get('Shared/Login').then(function (result) {
        element.replaceWith(result);
    });
}

这将呈现HTML,但范围不绑定在DOM元素上。
使用$compile。
link: function (scope, elem, attrs) {
    templateRepository.get('Shared/Login').then(function (result) {
        elem.html(result);
        $compile(elem.contents())(scope);
    });
}

这个按预期工作。

这里有什么区别?

2个回答

3

$compile:

将HTML字符串或DOM编译成模板,并生成一个模板函数,该函数可以用于链接作用域和模板。

编译是遍历DOM树并将DOM元素与指令进行匹配的过程。

因此,$compile会处理交给它的任何DOM元素上的Angular处理。

$compile期间,所有找到的指令中的Compile Function都会运行。请注意,每个指令的编译函数只执行一次,无论该指令有多少个实例。

当由$compile生成的模板函数被执行(“将作用域和模板链接在一起”)时,然后执行每个指令的链接函数(将作用域作为第一个参数传递)。

因此,$compile会转换DOM。在这种转换期间,对于该指令,运行的是指令的编译函数。

以下是一个小的演示,您可以尝试一下其中的执行顺序。


因此,指令的 compile 函数不会链接到作用域,只会从指令和其所附加的元素创建一个模板。如果是这样,那么使用 $compile 服务是我想要做的正确方式吗? - Sam
但请注意,无论是$compile还是执行生成的模板函数都不会将元素添加到DOM中。您可以拥有一个已编译的元素,但它尚未在DOM中,反之亦然。 - KayakDave
谢谢!没错,在这种情况下,它是在编译之前添加的,这样做完全没有问题。 - KayakDave
你能用指令编译函数完成相同的事情吗?还是必须在链接函数中进行,以便将作用域传递到编译函数中? - Sam
1
在编译中处理它有两个问题。首先,就像你提到的那样,在编译函数中没有可用的作用域。其次,对于一个指令,编译只会被调用一次,无论有多少个实例。因此,它就像是指令的构造函数。因此,使用编译函数,您不能拥有具有不同HTML的多个指令副本。 - KayakDave
显示剩余2条评论

1
我认为,编译函数更加灵活:
从文档中可以看到:

编译函数可以有一个返回值,可以是函数或对象。

返回(post-link)函数 - 等同于在编译函数为空时通过config对象的link属性注册链接函数。

返回一个带有通过pre和post属性注册的函数的对象 - 允许您在链接阶段控制何时调用链接函数。请参见有关预链接和后链接函数的信息。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接