Angular 1.5组件与旧指令 - 哪里是链接功能?

tro*_*orl 58 javascript angularjs angularjs-directive angular-directive

我一直在阅读这篇关于.component()Angular 1.5中新助手的最新文章,该文章应该可以帮助每个人最终迁移到Angular 2.一切看起来都很简单,但我找不到任何有关组件内DOM操作的信息.

template虽然有一个属性,它可以是一个函数,接受$element$attrs参数.我还不清楚这是否是link功能的替代品.它似乎并非如此.

jod*_*ate 72

编辑16年2月2日: 1.5文档现在包括组件:https://docs.angularjs.org/guide/component


基于一些阅读的一些想法(链接如下):

  • 组件不是指令的替代品.组件是一种特殊类型的指令,用于使用模板组织控制器.

  • 组件没有链接功能,控制器仍然不是您处理DOM操作的地方.

  • 如果需要DOM操作,则组件可以在链接函数中使用包含该DOM操作的其他指令.

我花了一段时间来弄清楚这一点,但是一旦我做了它就有了一些意义:组件是指令,但并非所有指令都是 - 或者需要 - 组件.

当我认为组件正在替换指令时,关于链接函数的问题是一个自然的问题,或者对我而言.为什么?因为我们已经被教导将DOM操作放在指令的链接函数中:"想要修改DOM的指令通常使用链接选项来注册DOM侦听器以及更新DOM." https://docs.angularjs.org/guide/directive.

如果你正在运行这个假设(组件替换指令),那么你会发现Angular文档没有回答这个问题,因为一旦你知道组件的目的,它就不是正确的问题.(组件在$ compileProvider文档中描述,而不是指令文档.)

背景阅读

我上面所说的实际上是对Todd Motto在组件和指令可能是最好的讨论(到目前为止)中所说的内容的改述:

https://www.reddit.com/r/angularjs/comments/3taxjq/angular_15_is_set_to_introduce_the_component/

将这些评论纳入更一般的文章可能会有所帮助.

大多数关于组件的文章没有提到链接功能(这并不意味着这些不是优秀的文章):

https://toddmotto.com/exploring-the-angular-1-5-component-method/

https://medium.com/@tomastrajan/component-paradigm-cf32e94ba78b#.vrbo1xso0

https://www.airpair.com/angularjs/posts/component-based-angularjs-directives

或者当提到链接功能时,它在括号中:

http://teropa.info/blog/2015/10/18/refactoring-angular-apps-to-components.html

一篇文章称组件"使用控制器而不是链接功能".但这不是"反而"的情况:控制器不是链接功能的替身.

  • 我不确定为什么你说在角度文档明确说明时你不应该对组件进行任何dom操作:"$ postLink() - 在这个控制器的元素和它的子元素被链接之后调用.类似于post-link函数这个钩子可以用来设置DOM事件处理程序并直接进行DOM操作." 你能解释为什么这对你没有吸引力吗? (3认同)

sur*_*ake 7

这使得以类似于使用Web组件或使用Angular 2的应用程序架构风格的方式编写应用程序变得更加容易.

组件的优点:

比plain指令更简单的配置提升了理智的默认值和针对基于组件的体系结构编写组件指令优化的最佳实践,这样可以更容易地升级到Angular 2

何时不使用组件:

对于依赖于DOM操作,添加事件侦听器等的指令,因为当您需要由属性或CSS类触发的指令时,需要高级指令定义选项(如priority,terminal,multi-element)时,编译和链接函数不可用而不是一个元素


Eka*_*eva 5

更新(从 2017 年 8 月 22 日开始):$inject 是在 AngularJS 中执行此操作的推荐方式。阅读样式指南: 样式指南链接和 AngularJS 文档:AngularJS 文档

为了在组件中使用 DOM 绑定而不是使用链接函数创建指令,您可以在控制器函数中注入“$element”或其他您需要的服务,例如

app.component('pickerField', {
    controller: PickerField,
    template: '<span>Your template goes here</span>'
  });

  PickerField.$inject = ['$element'];

  function PickerField(element) {
    var self = this;
    self.model = self.node.model;
    self.open = function() {
      console.log('smth happens here');
    };
    element.bind('click', function(e) {
      console.log('clicked from component', e);
      self.open();
    });
  }
Run Code Online (Sandbox Code Playgroud)

  • 我同意 - 如果需要将 $element 访问到组件中,您的方式是正确的。但我的论点是,如果您需要访问 $element,您应该使用指令而不是组件。我的理由是:如果你将 $element 注入到一个组件中,当你使用 $componentController 进行单元测试时,你将不得不通过 $compile 创建一个假的 $element。 (2认同)

tro*_*orl 2

好的,看来控制器现在是合适的位置,因为它是唯一可能的位置。此外,我们不能replace在组件帮助器中使用选项。