我有几个分离的Web组件,它们由角形元素制成,我将其导入一个主要的组件中,该组件具有路由器,是基础应用程序。 路线非常简单:
import { Component } from '@angular/core';
import { Router } from "@angular/router";
@Component({
selector: 'example',
template: '<component-one [variable]="toPass" (callback)="onCallback($event)"></component-one>',
styles: []
})
export class ExampleComponent {
public toPass: string = "Hello World!";
constructor(private router: Router) {}
onCallback(event) {
console.log(event);
this.router.navigate(['example-two']);
}
}
组件将执行应做的事情。
import { Component, Input, OnInit } from '@angular/core';
@Component({
selector: "component-one",
templateUrl: "./component-one.html",
styleUrls: ["./component-one.scss"],
encapsulation: ViewEncapsulation.Emulated,
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ComponentOne implements OnInit {
@Input() variable: string;
@Output() callback = new EventEmitter<any>();
constructor() {}
ngOnInit() {
console.log("Variable: ", this.variable);
}
someRandomButtonClicked() {
callback.emit({ data: "Callback Called" });
}
}
现在,当我启动主应用程序时,一切都按预期显示,回调工作正常,但变量未定义。 我的Webcomponents的@Input声明中缺少什么吗?
答案 0 :(得分:3)
由于您使用的是角度元素,因此请确保您的变量名使用 smallcaps 这样
@Input() myvariable: string
而非@Input() myVariable: string
在这里检查
https://github.com/angular/angular/issues/24871
答案 1 :(得分:1)
我认为您只是想念新语法:)
当您在输入名称周围使用[]时,您会告诉angular给您一个变量。如果您不使用它,则要求angular将其作为基本元素。
所以:
<component-one [variable]="myVar"
必须在组件中定义一个名为“ myVar”的变量
没有
<component-one variable="myVar"
Angular将“ myVar”作为字符串值
没用,但是有效:
<component-one [variable]="'myVar'"
您将新字符串作为变量
答案 2 :(得分:1)
您可以只在ComponentOne中初始化变量。那应该可以了
@Input() variable:String = “”;
答案 3 :(得分:1)
我认为这就是这里的解释:https://github.com/angular/angular/issues/29050。如果您在 ngOnChanges() 钩子中使用 console.log() 变量,您将获得正确的值,但在 ngOnInit() 中它们仍未定义。使用自定义元素时,钩子执行的顺序会发生变化。这就是为什么在你它是未定义的。就我而言,我仍在寻找如何强制 ngOnChanges() 先运行然后 ngOnInit() 但还没有运气。
答案 4 :(得分:1)
我遇到了这个问题大约两天,最后我找到了解决方案。
您需要做的是在您的子组件(您要公开的网络组件)中使用 ngOnChanges() 方法。因为这是为了检测 @Input() 字段的任何变化。
这里我留下了我的网络组件的代码片段:
@Component({
selector: 'app-shipment-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit, OnChanges {
@Input() domain;
@Output() response = new EventEmitter<string>();
constructor() {
}
ngOnInit(): void {
}
ngOnChanges(changes: SimpleChanges): void {
if (changes.domain) {
console.log("Domain URL: ", this.domain);
this.response.emit(this.domain);
}
}
}
答案 5 :(得分:0)
在您的代码中,将问题中显示的所有位置的String
更改为string
。看看是否可行。
String
是类型string
的构造函数。更多信息here
请参见distinction between string and String。
更新:
我有一种感觉,这与您使用的内联模板格式有关。
更改此
@Component({
selector: 'example',
template: '<component-one [variable]="toPass" (callback)="onCallback($event)"></component-one>',
styles: []
})
对此,
@Component({
selector: 'example',
template: `<component-one [variable]="toPass" (callback)="onCallback($event)"></component-one>`,
styles: []
})
看,我将template: ''
更改为此
template: ``
否则,内联模板字符串的解析可能会搞砸。
看看是否可行。
答案 6 :(得分:0)
ngOnChanges
。所以我尝试了“属性绑定”,效果很好。来自 angular.io:
Angular 中的属性绑定可帮助您设置属性值
直接地。属性绑定语法类似于属性绑定,但
而不是括号之间的元素属性,你在名称之前
带有前缀 attr 的属性,后跟一个点
更改以下实现
<custom-element name="{{userName}}"></custom-element>
(or)
<custom-element [name]="userName"></custom-element>
为此:
<custom-element [attr.name]="userName"></custom-element>
为了传递常量值,使用
<custom-element [attr.name]="'John'"></custom-element>
注意:您将在 ngOnChanges() 方法中获得该值。