下面是一个组件,我将在其他各种组件中进行扩展,以便重用一些代码。
import { Component } from '@angular/core';
@Component ({
selector: 'my-app',
template: ` <div>
<h1>{{appTitle}}</h1>
<div>To Tutorials Point</div>
</div> `,
})
export class AppComponent {
appTitle: string = 'Welcome';
ngOnInit(){
this.registerSomeSubscriptions();
}
registerSomeSubscriptions(){
this.subscribeSomething.subscribe((data)=>{
performSomeAction();
})
}
}
我可以像下面这样扩展它
import { Component } from '@angular/core';
@Component ({
selector: 'my-app',
template: ` <div>
<h1>{{appTitle}}</h1>
<div>To Tutorials Point</div>
</div> `,
})
export class ChildComponent extends AppComponent {
}
虽然我知道该组件的公共成员将在子组件中可用。
我的问题
答案 0 :(得分:2)
子组件可以使用与父组件相同的html模板,也可以拥有自己的html文件,在这种情况下,将不使用父组件的html。
如果要在子组件中使用父组件的html并进行一些修改,则可以重用父组件而不是继承它。
// add something specific to child/feature component here
<app-reusable-component></app-reusable-component>
// add something specific to child/feature component here
可重用组件的html以及在功能组件的html中添加的其他html都将可用。
使用组件交互-Input
和Output
在可重用组件和功能组件之间传递数据。
Input
-通过输入绑定将数据从要素组件传递到可重用组件
reusable-component.ts:
export class ReusableComponent implements OnInit {
@Input() dataIn: Observable<object>;
ngOnInit() {
dataIn.subscribe(data => {
// display data
});
}
}
feature-component.html:
...
<app-reusable-component [dataIn]="dataToDisplay$"></app-reusable-component>
...
feature-component.ts:
export class FeatureComponent implements OnInit {
public dataToDisplay$: Observable<object>;
ngOnInit() {
this.dataToDisplay$ = this.http.get(url);
}
}
Output
-将数据/事件从可重用组件发送到功能组件reusable-component.ts:
export class ReusableComponent implements OnInit {
@Input() dataIn: Observable<object>;
@Output() eventOut: EventEmitter<object> = new EventEmitter<object>();
ngOnInit() {
dataIn.subscribe(data => {
// display data
});
}
userInput(value) {
this.eventOut.emit(value);
}
}
feature-component.html:
...
<app-reusable-component [dataIn]="dataToDisplay$" (eventOut) ="handleUserData($event)"></app-reusable-component>
...
feature-component.ts:
export class FeatureComponent implements OnInit {
public dataToDisplay$: Observable<object>;
ngOnInit() {
this.dataToDisplay$ = this.http.get(url);
}
handleUserData(value) {
this.http.post(url, value);
}
}
通过这种方法,您可以在所有子/功能组件中重复使用父组件的模板,并且可以在子/功能组件中添加其他html内容,并在它们之间传递数据。
答案 1 :(得分:1)
如果只想将相同的模板用于子组件和父组件,则只需将该模板放入html文件中,并使用templateUrl
进行引用。您的订阅将被继承,并且您将能够从子组件访问受保护的公共变量和受保护变量。
现在,如果您想继承父模板但又能够进行模板修改,这会有点困难,因为angular不提供模板继承。
一种可能的替代方法是使用模板引擎生成html。在我们的一个项目中,我们使用nunjucks来解决此限制。
因此,基本上,您可以使用nunjucks模板指定父组件的html
parent.component.html.njk
<div>
Parent template
{% block specific %}
{% endblock %}
</div>
parent.component.ts
@Component ({
selector: 'app-parent',
templateUrl: `parent.component.html`, //Reference compiled template (not .njk)
})
export class ParentComponent
{
//...
然后,您还将子组件定义为从父模板继承的nunjucks模板
child.component.html.njk
{% extends '/path/to/parent/parent.component.html.njk' %}
{% block specific %}
Child content: {{childContent}}
{%endblock %}
child.component.ts
@Component ({
selector: 'app-child',
templateUrl: `child.component.html`, //reference .html, not .njk
})
export class ChildComponent extends ParentComponent
{
public childContent = "hello";
//Access to public/protected members and methods from parent componenent
最重要的是,我们有一个基本的监视脚本,该脚本监视.njk文件的更改并生成相应的html
watch.js
const nunjucks = require('nunjucks');
//Nunjuck config to use <$ and $> for tags, instead of {{ and }}, to avoid conflicting with angular
const nunjucksEnv = nunjucks.configure(
{
noCache: true,
tags:
{
variableStart: '<$',
variableEnd: '$>',
}
}
);
//Add watch loop here. Whenever a njk file changes, call the code below
nunjucks.render(njkTemplateFileThatJustChanged, {}, function (err, html)
{
if (!err)
{
let compiledPath = njkTemplateFileThatJustChanged.replace('.njk', '');
fs.writeFileSync(compiledPath, html);
}
}
答案 2 :(得分:0)
如果模板在文件中,则可以重复使用它。
@Component是装饰器,它为“组件”分配一些“元”数据,因此您不会从扩展类继承它。如果模板在单独的文件中,则可以在@Component装饰器的Select-Xml -Xml $Scans -XPath "//ValidatedOnline" | % node
#text
-----
true
属性中使用它。
答案 3 :(得分:0)
您可能无法扩展html,但是可以通过多种方式使用模板:
在服务中设置基本模板的TemplateRef
,并使用directive
在以后的任何地方使用它。
A:的缺点是,基本组件需要手动实例化,并且在内存中直到容器可见为止。 [请参阅示例-BaseOneComponent
]
B。如果模板没有太多绑定,则可以在根(AppComponent)
本身中对其进行初始化。
为占位符BaseTwoComponent
创建公用组件,并使用<ng-content>
从使用者组件[DerivedTwoComponent
]投影数据。您还可以为<ng-content>
创建多个占位符,并将它们与选择器一起使用。
选中此Angular Content Projection Guide,了解如何使用多个插槽进行内容投影。
Stackblitz:Template extension
答案 4 :(得分:0)
https://plnkr.co/edit/HNG0ndIErlOfVnMl?preview
刚刚在子组件模板中使用了父组件的选择器。检查我在app.ts
中添加的代码。