多平台统一管理软件接口,如何实现多平台统一管理软件接口
256
2023-04-17
浅谈angular4 ng
如果你尝试在 Angular 中编写可重复使用的组件,则可能会接触到内容投射的概念。然后你发现了
接下来我们来通过一个简单的示例,一步步介绍
Simple example
在本文中我们使用一个示例,来演示不同的方式实现内容投影。由于许多问题与Angular 中的组件生命周期相关,因此我们的主要组件将显示一个计数器,用于展示它已被实例化的次数:
import { Component } from '@angular/core';
let instances = 0;
@Component({
selector: 'counter',
template: '
})
class Counter {
id: number;
constructor() {
this.id = ++instances;
}
}
上面示例中我们定义了 Counter 组件,组件类中的 id 属性用于显示本组件被实例化的次数。接着我们继续定义一个 Wrapper 组件:
import { Component } from '@angular/core';
@Component({
selector: 'wrapper',
template: `
`
})
class Wrapper {}
现在我们来验证一下效果:
Targeted projection
有时你希望将包装器的不同子项投影到模板的不同部分。为了处理这个问题,
import { Component } from '@angular/core';
@Component({
selector: 'wrapper',
template: `
`,
styles: [`
.red {background: red;}
.blue {background: blue;}
`]
})
export class Wrapper { }
上面示例中,我们引入了 select 属性,来选择投射的内容:
This is not a counter
上述代码成功运行后,counter 组件被正确投影到第二个蓝色框中,而 span 元素最终会在全部红色框中。请注意,目标 ng-content 会优先于 catch-all,即使它在模板中的位置靠后。
ngProjectAs
有时你的内部组件会被隐藏在另一个更大的组件中。有时你只需要将其包装在额外的容器中即可应用 ngIf 或 ngSwitch。无论什么原因,通常情况下,你的内部组件不是包装器的直接子节点。为了演示上述情况,我们将 Counter 组件包装在一个
现在我们的 couter 组件会被投影到第一个红色框中。因为 ng-container 容器不再匹配 select="counter"。为了解决这个问题,我们必须使用 ngProjectAs 属性,它可以应用于任何元素上。具体如下:
通过设置 ngProjectAs 属性,终于让我们的 counter 组件重回蓝色框的怀抱了。
Time to poke and prod
我们从一个简单的实http://验开始:将两个
页面中会显示一个或两个框,如果我们包含两个框,它们的内容是显示 1 和 1 或 1 和 2?
答案是我们在最后一个
import { Component } from '@angular/core';
@Component({
selector: 'wrapper',
template: `
{{ show ? 'Hide' : 'Show' }}
`
})
class Wrapper {
show = true;
}
乍一看,似乎正常运行。但是如果你通过按钮进行切换操作,你会注意到计数器的值不会增加。这意味着我们的计数器组件只被实例化了一次 - 从未被销毁和重新创建。难道这是 ngIf 指令产生的问题,让我们测试一下 ngFor 指令,看看是否有同样的问题:
import { Component } from '@angular/core';
@Component({
selector: 'wrapper',
template: `
`
})
class Wrapper {
items = [0, 0, 0];
}
以上代码运行后与我们使用多个
The explanation
这种行为有两个原因:期望一致性和性能。什么 "期望的一致性" 意味着作为开发人员,可以基于应用程序的代码,猜测其行为。假设我写了以下代码:
很显然计数器将被实例化一次,但现在假如我们使用第三方库的组件:
如果第三方库能够控制 counter 组件的生命周期,我将无法知道它被实例化了多少次。其中唯一方法就是查看第三方库的代码,了解它们的内部处理逻辑。将组件的生命周期被绑定到我们的应用程序组件而不是包装器的意义是,开发者可以掌控计数器只被实例化一次,而不用了解第三方库的内部代码。
性能的原因更为重要。因为 ng-content 只是移动元素,所以可以在编译时完成,而不是在运行时,这大大减少了实际应用程序的工作量。
The solution
为了让包装器能够控制其子元素的实例化,我们可以通过两种方式完成:在我们的内容周围使用
包装器不再使用
@Component({
selector: 'wrapper',
template: `
{{ show ? 'Hide' : 'Show' }}
`
})
class Wrapper {
show = true;
@ContentChild(TemplateRef) template: TemplateRef;
}
现在我们的 counter 组件,每当我们隐藏并重新显示时都正确递增!让我们再验证一下 *ngFor 指令:
@Component({
selector: 'wrapper',
template: `
`
})
class Wrapper {
items = [0, 0, 0];
@ContentChild(TemplateRef) template: TemplateRef;
}
上面代码成功运行后,每个盒子中有一个计数器,显示 1,2 和 3,这正是我们之前预期的结果。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~