Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/77.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么Angular中的子组件应通过NgModule注册?封装呢?_Angular - Fatal编程技术网

为什么Angular中的子组件应通过NgModule注册?封装呢?

为什么Angular中的子组件应通过NgModule注册?封装呢?,angular,Angular,我在其他框架和体系结构原则方面有一些经验,我绝对不理解Angular团队的决定,即反对RC6中组件的directivies属性,而支持NgModule中的声明 通常架构是关于封装的,但是突然之间,如果某个组件的某些功能应该由子组件封装,那么子组件“泄漏”到模块,现在应该在模块中注册 那么,为什么在一个模块中有一个组件的逻辑树,所有组件都应该在模块中注册为“普通” 这种方法不会让ngmodule大量导入和删除吗 我知道我们可以将所有内容拆分为多个模块,但在单个模块中,例如全局“加载并注册”会让我记

我在其他框架和体系结构原则方面有一些经验,我绝对不理解Angular团队的决定,即反对RC6中组件的
directivies
属性,而支持NgModule中的
声明

通常架构是关于封装的,但是突然之间,如果某个组件的某些功能应该由子组件封装,那么子组件“泄漏”到模块,现在应该在模块中注册

  • 那么,为什么在一个模块中有一个组件的逻辑树,所有组件都应该在模块中注册为“普通”

  • 这种方法不会让ngmodule大量导入和删除吗

  • 我知道我们可以将所有内容拆分为多个模块,但在单个模块中,例如全局“加载并注册”会让我记住html中的一堆全局
    script[src]
    标记。我以为我们已经远离了这个模式,但它看起来像是有角度的回归

    我好像错过了什么,有人能给我解释一下吗


    [编辑1](中断AOT编译,请参阅
    EDIT-2
    ) 现在,我们模拟嵌套组件声明,以便每个组件导出已使用组件的列表,然后在NgModule中,我们遍历所有根组件,收集它们的依赖项,并预处理完整的
    声明

    看起来是这样的:

    src/app    
        - /components/home-view/
            - /toolbar
                /menu-button
                    - menu-button.component.ts
    
                - toolbar.component.ts
    
            - home-view.component.ts
    
        - app.module.ts
    
    app.module.ts

    从“./components/home view/home view.component”导入{HomeViewComponent};
    命名空间Utils{
    导出函数平坦指示(arr:any[]=[]):any[]{
    常量声明=arr.reduce((compos,compo)=>{
    复合推送(…修饰指令(复合指令),复合;
    返回组件;
    }, []);
    返回数组.from(新集合(声明));
    }
    }
    @NGD模块({
    声明:Utils.advandirectives([
    HomeViewComponent,
    ]),
    引导:[AppComponent]
    })
    导出类AppModule{}
    
    /components/home view/home view.component.ts

    从'./toolbar/toolbar.component'导入{ToolbarComponent};
    @组成部分({
    选择器:“应用程序主视图”,
    模板:``,
    })
    导出类HomeViewComponent{
    静态指令=[ToolbarComponent]
    }
    
    /components/home view/toolbar/toolbar.component.ts

    import{MenuButtonComponent}来自“./menu-button/menu-button.component”;
    @组成部分({
    选择器:“应用程序工具栏”,
    模板:``,
    })
    导出类工具栏组件{
    静态指令=[MenuButtonComponent]
    }
    
    /components/home view/toolbar/menu button/menu button.component.ts

    @组件({
    选择器:“应用程序菜单按钮”,
    模板:``,
    })
    导出类菜单按钮组件{}
    
    这种方法是否有任何警告


    [编辑2] 在DEV中,上述方法运行良好,但AOT编译会因错误而中断

    ERROR in : Cannot determine the module for class 'name' in 'path'! Add 'name' to the NgModule to fix it.
    
    因此,我们必须回到简单的声明。有什么解决方案可以让aot编译更灵活

    多谢各位

  • NgModule
    概念在发布之前就出现了,它提供了创建库/模块的标准方法,添加了有效的导入系统和延迟加载功能。在许多方面,它与任何其他模块/包系统(即声明模块依赖项、模块公共导出等)类似,但由于JS的性质存在一些限制

  • 您可以在设计模块时选择粒度级别,以避免冗长的导入/声明。库倾向于使用每个组件模块的策略来最小化大小影响(您只需要导入所需的模块,而不是更多),但在这种情况下,有时您必须导入许多模块

  • 问题是,在AOT中,所有组件引用都必须在编译过程中静态解析,您不能使用动态代码,例如
    flatndirectives
    函数,因为它不可静态分析。请看,我怀疑是否有可能编写可以删除重复项的函数,但可能您甚至可以使用重复项,即
    声明:[HomeViewComponent.directives]
    (需要检查生成的代码)


  • 谢谢你,1。你能具体说明一下限制是什么吗?2.它对应用程序开发意味着什么:假设我刚刚开始执行。应用程序。我有一个根
    NgModule
    ,然后添加
    工具栏
    组件。之后,我决定在工具栏中添加
    菜单按钮
    组件。该组件仅在
    工具栏中使用
    组件,是否必须为工具栏创建NgModule?此外,当
    MenuButton
    ItemList
    组件时,我是否需要为
    MenuButton
    创建
    NgModule
    ,依此类推。当问题仍然是
    @组件
    中的
    指令
    属性时,可以解决该问题。然后aot可以分析组件树。这就是为什么我不明白为什么财产被移走了。您可以浏览NgModule的angular api页面,例如有
    声明
    字段,angular无法自动检测模块内部使用的组件,
    entryComponents
    必须包含要动态创建的组件。在其他UI框架中通常不需要这种注册。2.若您不想创建库或不使用延迟加载,那个么您应该可以使用1个模块。如果您愿意,您可以创建任何其他适合您需要的模块结构。3.也许,我猜是编译器优化。