如何将JSON对象传递给Angular自定义元素

7

我使用CUSTOM_ELEMENTS_SCHEMA在Angular 7中创建了一个自定义元素。 我的app.module.ts如下:

    export class AppModule {
     constructor(private injector: Injector) {}
     ngDoBootstrap() {
       this.registerCustomElements();
     }

    registerCustomElements() {
      const HeaderElement = createCustomElement(AppComponent, {
        injector: this.injector
      });
      const FooterElement = createCustomElement(BcAngFooterComponent, {
        injector: this.injector
      });
      customElements.define("header-element", HeaderElement);
      customElements.define("footer-element", FooterElement);
  }
}

我已经在我的app.component.html中引用了这些自定义元素,如下所示:

<footer-element footer-data="footerInputData"></footer-element>

这个footerInputData在我的app.component.ts文件中被引用为一个字符串。

 export class AppComponent {
  footerInputData: any = {title: "Page Title"};
}

在我的自定义元素的 HTML 中,我使用插值来显示传递给它的输入数据。

<div class="nav-list-wrap">
        {{footerData}}
</div>

当页面加载时,我看不到对象显示。相反,它显示为“footerInputData”。
如何使我的自定义元素从我的app.component.ts文件中获取数据,而不是将数据显示为字符串。
另外,JSON对象可以传递给我的自定义元素吗?

1
你能为此创建一个 StackBlitz 吗? - Pardeep Jain
@Prashanth 你如何克服这个问题?我现在正在面对这个问题。 - Paulo Pereira
3个回答

3

自定义元素是用于在Angular包装器外部使用的,尽管您可以在Angular包装器内部使用它们。 当您在Angular包装器外部使用它们时,需要像这样使用它们

<footer-element name='{"title": "Page Title"}'></footer-element> 

属性值应该被字符串化,如果你传递的是JSON,则JSON字符串应该严格格式化。

当你在Angular包装器中使用它时,可以使用Angular选择器,并且可以像以前一样传递数据。

<app-custom [name]="name"></app-custom>
//ts file
name = {title:"this is title"}

自定义组件.ts文件

@Component({
  selector: 'app-custom',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent {
  @Input() name: any;
}

app.module.ts

@NgModule({
  imports: [BrowserModule, FormsModule],
  declarations: [AppComponent, MainComponent],
  entryComponents:[
    AppComponent, MainComponent
  ]
})
export class AppModule {
  constructor(private injector: Injector) { }
  ngDoBootstrap() {
    //bootstraping angular app
    const AppElement = createCustomElement(MainComponent, { injector: this.injector });
    customElements.define('my-app', AppElement);

    //bootstraping custom element
    const el = createCustomElement(AppComponent, { injector: this.injector });
    customElements.define('footer-element', el);
  }
}

查看工作示例


很好的例子!非常感谢!现在我正在尝试找出正确的Angular语法,将变量作为对象的一部分传递进去。 - bou2you

1

这是我唯一让它能为我工作的方法,希望这可以对你们有所帮助: 注意:每次更改属性值时,TypeScript代码将被触发:

<body>
 <my-element settings=""></my-element>
 <script>
    var myConfig = {name: "oswaldo"}

    var element = document.getElementsByTagName("my-element")[0];
    if(element){
      element.setAttribute("settings", JSON.stringify(myConfig));
    }
  </script>
</body>

这是我的.ts文件中的内容:

@Component({
  selector: 'my-element',
  templateUrl: './my-element.component.html',
  styleUrls: ['./my-element.component.less']
})
export class MyElementComponent implements OnInit {

  @Input('settings') set settings(init: any) {
    if (init) {
      const myset = JSON.parse(init);
      console.log(myset.name);
   }
}

0

你的 footer-data 中应该有一个 [],在更改后可能需要一个 changeDetectRef 来重新检查值。

步骤1 ng new testing

步骤2 ng g c footer

步骤3 在 app.module.ts

import { createCustomElement } from '@angular/elements';
import { FooterComponent } from './footer/footer.component';
...
@NgModule({
  declarations: [AppComponent, FooterComponent],
  imports: [BrowserModule],
  providers: [],
  bootstrap: [AppComponent],
  entryComponents: [FooterComponent],
  schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class AppModule { 
  constructor(private injector: Injector) {
    const customElement = createCustomElement(FooterComponent, { injector });
    customElements.define('some-component', customElement);
  }
  ngDoBootstrap() { }
}

第四步 在 app.component.html

<some-component [data]="footerInputData"></some-component>

第五步 在 app.component.ts

...
export class AppComponent {
   footerInputData = {"testing": "abc"}
}

第六步,在 footer.component.ts 文件中

import { Component, OnInit, Input, AfterViewChecked } from '@angular/core';
import { ChangeDetectorRef } from '@angular/core';

@Component({
  selector: 'app-footer',
  templateUrl: './footer.component.html',
  styleUrls: ['./footer.component.scss']
})
export class FooterComponent implements OnInit, AfterViewChecked {

  @Input() public data: any;
  displayedData = ""

  constructor(
    private cdRef:ChangeDetectorRef
  ) { }

  ngOnInit() {

  }

  ngAfterViewChecked()  {
    this.displayedData = this.data
    this.cdRef.detectChanges();
  }
}

第七步,在 footer.component.html 文件中

<p>
  {{ displayedData | json }}
</p>


我正在使用Angular和AEM,为此我正在使用自定义Angular元素。因此,我需要一个将对象数组传递给自定义元素的解决方案。 - Prashanth
@Prashanth 我已经编辑了答案。它能够通过上面的示例传递json。如果适合你的情况,请告诉我。 - hugomac

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接