首页 >> 大全

这是您需要了解的有关Angular中的动态组件的知识

2023-09-15 大全 36 作者:考证青年

动态组件传值props__动态组件传值方法

像专业人士一样动态创建组件

如果您一直在使用进行编程,则可能已经习惯于即时生成HTML字符串,通过$ 服务运行它们,并链接到数据模型(作用域)以获得双向数据绑定。

const = ' on the fly: {{name}}' const = $(); const = $scope.$new(); .name = ' ' // link data model to a ();

在中,指令可以以任何可能的方式修改DOM,而框架不知道修改的内容。 但是,这种方法的问题与任何动态环境都一样-很难针对速度进行优化。 动态模板评估当然不是被视为缓慢框架的主要原因,但它无疑有助于声誉。

在研究了内部很长时间之后,似乎新的框架设计很大程度上是由对速度的需求所驱动。 您会在源代码中找到许多类似这样的评论:

: to this is ! Note: We use one type for all nodes so that loops that loop over all nodes of a stay ! For , we want to check and the list every five .

因此,较新的框架中的成员决定提供较少的灵活性以换取更大的速度。 并介绍了JIT和AOT编译器以及静态模板。 和工厂。 和工厂解析器。 以及许多其他对社区不熟悉的事物。 但是不用担心。 如果您以前曾经遇到过这些概念,并且想知道继续阅读这些概念并获得启发。

组件工厂和编译器

在中,每个组件都是从工厂创建的。 并且工厂由编译器使用您在@装饰器中提供的数据生成。 如果在阅读了许多网络文章之后,您仍然不确定该装饰器的作用是阅读《 实现自定义组件装饰器》 。

引擎盖下的使用视图的概念。 运行中的框架本质上是一棵视图树。 每个视图由不同类型的节点组成:元素节点,文本节点等。 每个节点在其用途上都有专门的用途,因此处理此类节点所需的时间尽可能短。 每个节点都有各种提供程序,例如和。 每个节点都知道如何响应诸如和之类的查询。

每个节点都有很多信息。 现在,为了优化速度,在构建节点时必须提供所有这些信息,并且以后无法更改。 这就是编译过程的工作-收集所有必需的信息,并将其封装为组件工厂的形式。

假设您定义一个组件及其模板,如下所示:

@({ : 'a-comp', : 'A ' }) class {}

编译器使用这些数据生成以下组件工厂:

(l) { (0,[ (l()(),(0,null,null,1, 'span' ,...)), (l()(),(null,[ 'My name is ' ,...])) ]

它描述了组件视图的结构,并在实例化组件时使用。 第一个节点是元素定义,第二个节点是文本定义。 您可以看到,通过参数列表实例化每个节点时,都会获得所需的信息。 解析所有必需的依赖项并在运行时提供它们是编译器的工作。

如果您有权访问工厂,则可以轻松地从中创建组件实例,并使用将其插入DOM。 我已经在探索 DOM操作中写过它。 它是这样的:

class { @("vc", {read: }) vc: ; () { this.vc.( ); } }

因此,现在的问题是如何访问组件工厂,我们很快就会看到。

_动态组件传值props_动态组件传值方法

模块和lver

尽管也有模块,但缺少指令的真实名称空间。 总是存在冲突的可能性,并且没有办法将实用程序指令封装在特定模块中。 幸运的是,吸取了教训,现在为声明式类型(指令,组件和管道)提供了适当的命名空间。

就像在中一样,新框架中的每个组件都是某个模块的一部分。 组件本身并不存在,如果要使用其他模块中的组件,则必须导入该模块:

@({ // with like // ngIf, ngFor, etc. : [], ... }) class {}

反过来,如果一个模块要提供某些组件供其他模块组件使用,则必须导出这些组件。 这是的工作方式:

const : [] = [ , , , NgIf, ... ]; @({ : [, ...], : [, ...], ... }) class { }

因此,每个组件都绑定到一个特定的模块,并且您不能在不同的模块中声明相同的组件。 如果这样做,将会出现错误:

Type X is part of the of 2 : ...

编译应用程序时,它将获取在模块的中定义或在组件模板中找到的组件,并为其生成组件工厂。 您可以在“源”选项卡中看到这些工厂:

_动态组件传值方法_动态组件传值props

在上一节中,我们确定了如果可以访问组件工厂,则可以使用它来创建组件并插入视图中。 每个模块都为其所有组件提供了便利的服务,以使组件出厂。 该服务是lver 。 因此,如果您在模块上定义了并希望保留其工厂,则可以从属于该模块的组件中使用此服务:

class { ( : lver) { // now the `f` a to the cmp const f = this..ory(); }

仅当两个组件都在同一模块中定义或导入具有已解决组件工厂的模块时,此方法才有效。

动态模块加载和编译

但是,如果您的组件是在另一个模块上定义的,而您实际上并不需要该组件,那么该组件又该如何加载呢? 我们能做到这一点。 这将类似于路由器使用配置选项所做的事情。

有两种方法可以在运行时加载模块。 第一个是使用提供的er 。 如果您将用作加载程序,则路由器将其用于加载子路由。 它具有一个公共方法加载,该加载将模块加载到浏览器并编译该模块及其中声明的所有组件。 此方法采用具有模块和导出名称的文件路径,并返回 :

.load('path/to/file#')

如果未指定导出名称,则加载的文件将使用默认的导出名称。 要注意的另一件事是er需要进行一些注入的DI设置,因此您应将其定义为这样的提供程序:

: [ { : r, : er } ]

您当然可以指定要提供的任何令牌,但是路由器模块使用r,因此使用相同的方法可能是一件好事。

因此,这是加载模块并获取组件工厂的完整代码:

@({ : [ { : r, : er } ] }) class t { ( : , : r) { } () { this. .load('app/t.#') .then(() => { const = .(this.); const r = r; const = r.ory(); // a and it to the view const = .(this.); this..(.); }) } }

但是使用er存在一个问题。 在后台 ,它使用编译器的方法。 此方法仅为在模块的中声明或在组件模板中找到的组件创建工厂。 但是,如果您不想将组件声明为入口组件怎么办? 有一个解决方案-自己加载模块并使用方法。 它为模块上的所有组件生成工厂,并将它们作为的实例返回:

class { : []; : ;

这是完整的代码,显示了如何自己加载模块并访问所有组件工厂的方法:

() { .('app/t.').then(() => { (.) .then(() => { const m = ..(this.); const = [0]; const cmp = .(this., [], null, m); }) }) }

请记住,这种方法使用了不支持作为公共API的编译器。 这是文档所说的 :

此列表中的一个有意遗漏的是@ / ,它目前被认为是低级api,并且可能会进行内部更改。 这些更改不会影响使用更高级别的api(命令行界面或通过@ / -b​​-进行的JIT编译)的任何应用程序或库。 只有非常特定的用例才需要直接访问编译器API(主要是IDE,lint等的工具集成)。 如果您正在从事这种集成,请首先与我们联系。 动态创建组件

从前面的部分中,您了解了如何在中创建动态组件。 您知道此过程需要访问放置在模块上的组件工厂。 到目前为止,我使用的模块是在运行时之前定义的,可以急切或延迟地加载。 但是,好处是您不必事先定义模块然后再加载它们。 您可以像在中一样动态地创建模块和组件。

让我们以我最初展示的示例为例,看看如何在中实现相同的效果。 因此,这再次是示例:

const = ' on the fly: {{name}}' const = $(); const = $scope.$new(); .name = ' ' // link data model to a ();

创建动态内容并将其附加到视图的一般流程如下:

定义一个组件类及其属性并装饰该类 定义模块类,将组件添加到模块声明中并装饰模块类 编译模块和所有组件以掌握组件工厂

该模块只是一个带有装饰器的类。 组件也是如此。 由于装饰器是简单的函数,并且在运行时可用,因此我们可以随时使用它们来装饰类。 以下是动态创建和附加组件的方法:

() { const = ' on the fly: {{name}}'; const = ({: })(class {}); const = ({: []})(class {}); () .then(() => { const f = [0]; const = f.(this., [], null, this._m); ..name = ''; this.vc.(.); }) }

您可能希望在装饰器中将匿名类替换为命名类,以获得更好的调试信息。

销毁组件

最后一件事是,如果您手动添加了组件,请不要忘记在销毁父组件时销毁它们:

() { if(this.) { this..(); } } 您发现文章中的信息有帮助吗?

_动态组件传值方法_动态组件传值props

From:

关于我们

最火推荐

小编推荐

联系我们


版权声明:本站内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 88@qq.com 举报,一经查实,本站将立刻删除。备案号:桂ICP备2021009421号
Powered By Z-BlogPHP.
复制成功
微信号:
我知道了