【问题标题】:Creating reusable UI components创建可重用的 UI 组件
【发布时间】:2014-08-26 10:33:39
【问题描述】:

在 jQuery 中,您可以创建可重用的 UI 组件。在 AngularJS 中,我知道使用指令是执行此操作的等效方式。 Directive 语法包含一个 Link 属性,您可以在其中操作 DOM。但这就是我感到困惑的地方。 AngularJS 是为了避免操纵 DOM,因为 AngularJS 在内部操纵 DOM,那么你为什么要这样做呢?有没有更好的方法来做到这一点而无需实际操作 DOM?

【问题讨论】:

    标签: angularjs


    【解决方案1】:

    您从哪里得到所有 DOM 操作都是坏事的想法?如果没有对 DOM 进行操作,怎么会渲染任何东西?在 控制器Angular 的上下文之外 中弄乱 DOM 是个坏主意,但在指令中你插入 Angular 并且可以安全地进行 DOM 更改而不会破坏任何东西。

    您基本上是在问如何在不操作 DOM 的情况下操作 DOM,这是没有意义的。

    继续在链接函数中做你的事情,这很好。

    【讨论】:

    • 如何保证安全地进行 DOM 更改?如果您正在操作的 DOM 部分正在由 Angular 在父级别操作怎么办。我可以在这里看到可能的冲突。
    • 链接函数在元素附加到 DOM 时运行,Angular 的任何其他部分如何能够干扰?
    • 如果我的 DOM 操作修改了父类,而父类是由 ng-class 设置的,那将被视为冲突。
    • 对,我明白你的意思,但那可能是要添加到“不要那样做”列表中的内容。如果我愿意,我可以在控制器层次结构中创建类似的问题。指令仍然是进行自定义 DOM 操作的地方。
    • 如果您使用一些第三方 Angular UI 代码,该代码的开发人员可能没有记录“不要那样做”。如果您正在编写自己的代码,您可能永远不会遇到这个问题,但我已经看到 jQuery UI 控件确实会在嵌入的代码中操纵父 DOM 属性和样式,所以我认为 angularJS 可能会出现类似的问题。
    【解决方案2】:

    在某些时候,您将不得不以某种方式操作 DOM,但在 95% 的情况下,您可以坚持使用 angular 的内置指令,例如 ng-if、ng-hide/show、ng -switch、ng-repeat 等...

    但是这些都是指令,所以 Angular 并没有在“内部”操作 DOM,它通过指令来操作,就像它的本意一样......

    请记住,在您的指令模板中,您可以使用其他指令,因此您的指令可以专注于自己的任务。

    【讨论】:

    • so angular isn't manipulating the DOM "internally" 完全相反。如果 Angular 不进行 DOM 操作,你认为会如何渲染任何东西?
    • 认为你误解了我试图在那里提出的观点,ng-if 指令操纵 DOM,ng-bind 指令操纵 DOM 等等......所以没有“内部”的东西在 Angular 中,这些指令使用与任何人都可以在其自定义指令中使用的完全相同的 API……因此,它在“公共”API 的一部分中完成,而不是在内部完成。
    • 编译和链接的整个过程都需要做DOM操作,它读取html替换指令(运行它们编译+链接函数)并重新插入到DOM中。所以内部 Angular 需要使用 DOM 操作和指令只添加自定义 DOM 操作,而 Angular 完成其余的工作。你可以说指令执行 DOM 操作(并且用户代码应该只使用指令来操作 DOM),但并不是说 Agnular 内部不这样做。
    • 你说的 $compile 服务,witch 也是公开的。除此之外,它实际上并没有按照您对所有指令的想法执行,它取决于天气或该指令是否指定了模板。如果不是,它实际上不会替换 DOM 中的任何内容。 (至少在阅读代码时没有显示)......它向其中添加了一些类和数据,因此它执行内部 DOM 操作非常公平,但对于 IMO 的主题而言无关紧要。
    • 除了初始引导,(这并不是真正从指令调用 $compile),大多数使用 $compile 将在指令中,您实际上必须输入“根节点”如果它们尚未在其中,则将 $compile 到您自己的 DOM 中。在某些情况下,为此使用 $animate 服务是有意义的。我说在大多数情况下是因为我实际上认为 UI-Bootstrap 团队在进行模式对话框时将 $compile 的使用扩展到服务......并不是他们必须这样做。
    【解决方案3】:

    使用 $rootScope 中的 $new(isolate) 方法来创建可重用的 UI 组件。将隔离设置为真。不要在你的 UI 组件之外操作任何东西:

    如果为真,则范围在原型上不会继承自 父范围。范围是孤立的,因为它看不到父范围 特性。创建小部件时,小部件不要 不小心读取了父状态。

    https://docs.angularjs.org/api/ng/type/$rootScope.Scope

    【讨论】:

    • 在指令中大多数时候你不需要在指令中调用 $new (除非你使用 translude 函数手动转换)你只需使用 scope: truescope: {} 第二个将创建隔离范围,您可以将其作为链接函数中的第一个参数进行访问。
    猜你喜欢
    • 1970-01-01
    • 2021-04-20
    • 1970-01-01
    • 2016-03-10
    • 2014-10-30
    • 1970-01-01
    • 2017-07-27
    • 1970-01-01
    • 2011-05-17
    相关资源
    最近更新 更多