AngularJS: ngInclude与指令的区别

93
我不太明白何时使用指令,何时更适合使用nginclude。以这个例子为例:我有一个局部文件“password-and-confirm-input-fields.html”,用于输入和确认密码的HTML。我在注册页面和更改密码页面下同时使用它。这两个页面各自有一个控制器,而局部文件没有专门的控制器。
那么我应该使用指令还是ngInclude呢?

我会每次选择指令,但我很好奇更有经验的Angular专家会说什么。 - Austin Mullins
1
如果它真的是一个独立的组件,那么它可能应该有自己的控制器与之关联。在我看来,我会使用partial - 但是,我很想听听更多的意见。 - tymeJV
4
如果那个部分需要任何JS代码,请使用指令。如果只是HTML,使用ngInclude。 - Daniel Beck
1个回答

122
一切都取决于您对代码片段的要求。个人来说,如果代码没有任何逻辑或甚至不需要控制器,则使用ngInclude。通常我会把更大的“静态”html片段放在这里,以避免杂乱无章的视图(例如:大型表格数据已经从父级控制器中获取,使用 <div ng-include="bigtable.html" /> 比所有这些代码混杂在视图中更干净)。
如果涉及到逻辑、DOM操作或需要在不同情况下定制(即以不同方式呈现)使用,则指令是更好的选择(它们可能一开始有些令人生畏,但它们非常强大,给它时间)。
ngInclude有时会受其外部$scope / interface影响。比如一个大而复杂的重复器。由于这个原因,这两个界面是相互关联的。如果主$scope发生变化,则必须更改所包含的部分的逻辑或代码。
另一方面,指令可以具有显式作用域/控制器等。因此,如果您正在考虑多次重复使用某些东西的情况,您可以看到拥有自己的连接范围将使生活更轻松,更不容易混淆。
此外,每当您需要与DOM进行交互时,都应使用指令。这使得测试更加方便,并将这些操作从控制器/服务等中解耦出来,这是您想要的!
提示:如果您关心IE8,请确保不使用restrict: 'E'!虽然有解决方法,但这很烦人。只需简化生活并坚持使用属性/等。例如: <div my-directive />

组件 [更新于 2016年3月1日]

在Angular 1.5中添加了一个组件(Component),它实际上是对 .directive() 的包装。大部分情况下应该使用组件,因为它默认情况下可以移除很多样板指令代码,例如:restrict: 'E', scope : {}, bindToController: true。我强烈建议您在应用程序中几乎所有地方都使用它们,以便更轻松地过渡到 Angular2。

总之:

你应该大多数时间使用组件和指令

  • 更易扩展
  • 可以模板化并将文件放在外部(类似 ngInclude)
  • 可以选择在指令中使用父级作用域或自己的隔离作用域。
  • 更好地在应用程序中重用


更新于 2016年3月1日

现在 Angular 2 慢慢地围绕着我们,我们已经知道了一般的格式(当然还会有一些变化),只是想要补充说明做 components 很重要(有时需要指令,例如需要使用 restrict: 'E')。

组件很类似于 Angular2 的@Component。我们这样封装逻辑和 HTML 内容在一个地方。


确保您将尽可能多的东西封装在组件中,这将使过渡到 Angular 2 更加容易!(如果您选择进行迁移)

这是一篇不错的文章,描述了使用指令进行迁移的过程(当然,如果您要使用组件,则非常相似):http://angular-tips.com/blog/2015/09/migrating-directives-to-angular-2/


5
我同意这个答案。指令的学习曲线陡峭,但一旦掌握了它,就会获得很大回报。 - Jazzy
1
当然,但它总是以某种方式完全连接到父控制器。指令可以在模板加载时在其内部创建控制器。如果您希望,它可以完全分离。 - Mark Pieszak - Trilon.io
到目前为止,我对指令最大的问题在于它们的渲染方式:总是立即加载。如果我创建了一个带有多个选项卡的页面,我通常只想在显示该选项卡时才加载和渲染它(并非总是如此)。但是指令会立即加载。这也使得它们在递归应用程序(如树视图)中几乎无法使用。对于这些情况,包含似乎更好用。 - Arwin
1
你可以将这个概念抽象成一个工厂或其他东西,这样你就可以在link函数中直接调用它,然后就完成了!不过如果能够内置到指令中就更好了,毫无疑问 :( @Arwin - Mark Pieszak - Trilon.io
在你的回答中,你说在ie8中使用带有“E”选项的指令是不安全的。但在更新中,你说组件是以“E”选项为前提定义的。这对于组件来说是否也是一样的,或者它们有一个开箱即用的解决方法? - netalex
显示剩余6条评论

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