Angular Elements:@Input装饰器无法使用变量

时间:2018-09-27 15:57:16

标签: angular custom-element angular-elements

我有几个分离的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声明中缺少什么吗?

7 个答案:

答案 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() 方法中获得该值。