最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to pass JSON object to angular custom elements - Stack Overflow

programmeradmin0浏览0评论

I have created an custom element in angular 7 using CUSTOM_ELEMENTS_SCHEMA. My app.module.ts is as follows:

    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);
  }
}

I have referenced these custom elements in my appponent.html as below:

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

This footerInputData is referenced in my appponent.ts file as a string.

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

Inside the HTML of my custom element, I have used interpolation to display the data passed to it as an input.

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

When the page loads, I do not see the object displayed. Instead, it is showing 'footerInputData'.

How to make my custom element fetch the data from my appponent.ts file, instead of displaying the data as a sting.

Also, can JSON objects be passed to my custom element?

I have created an custom element in angular 7 using CUSTOM_ELEMENTS_SCHEMA. My app.module.ts is as follows:

    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);
  }
}

I have referenced these custom elements in my app.ponent.html as below:

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

This footerInputData is referenced in my app.ponent.ts file as a string.

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

Inside the HTML of my custom element, I have used interpolation to display the data passed to it as an input.

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

When the page loads, I do not see the object displayed. Instead, it is showing 'footerInputData'.

How to make my custom element fetch the data from my app.ponent.ts file, instead of displaying the data as a sting.

Also, can JSON objects be passed to my custom element?

Share Improve this question asked Feb 13, 2019 at 4:44 PrashanthPrashanth 1,3053 gold badges12 silver badges13 bronze badges 2
  • 1 Can you create stackblitz for the same? – Pardeep Jain Commented Feb 13, 2019 at 4:58
  • @Prashanth how do you overe this problem? I am facing this right now. – Paulo Pereira Commented Oct 2, 2019 at 14:18
Add a ment  | 

3 Answers 3

Reset to default 3

Custom elements are intended to use outside the angular wrapper, even though you can use them inside the angular wrapper. when you use them outside the angular wrapper you need to use it like this

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

attribute value should be stringified, if you are passing json the json string should be strictly formatted.

When you use it inside the angular wrapper you can use it with the angular selector, and can pass data as the same old method.

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

custom ponent.ts file

@Component({
  selector: 'app-custom',
  templateUrl: './app.ponent.html',
  styleUrls: [ './app.ponent.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);
  }
}

Check out the working example

This was the only way I got this working for me, hope this could help to you guys: Note: each time you change the attribute value the type script code will be fired:

<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>

This is what is in my .ts file:

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

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

There should be a [] in your footer-data and there may need a changeDetectRef needed to re-check the value after changes.

Step 1 ng new testing

Step 2 ng g c footer

Step 3 In app.module.ts

import { createCustomElement } from '@angular/elements';
import { FooterComponent } from './footer/footer.ponent';
...
@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-ponent', customElement);
  }
  ngDoBootstrap() { }
}

Step 4 In app.ponent.html

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

Step 5 In app.ponent.ts

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

Step 6 In footer.ponent.ts

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

@Component({
  selector: 'app-footer',
  templateUrl: './footer.ponent.html',
  styleUrls: ['./footer.ponent.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();
  }
}

Step 7 In footer.ponent.html

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

发布评论

评论列表(0)

  1. 暂无评论