Welcome to MLink Developer Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
170 views
in Technique[技术] by (71.8m points)

javascript - SSI render web component not working using res.send() and #include virtual

I'm working in a project and I'm stuck in this thing. I don't know if I'm missing something or something is failing

I want to render a custom element using Express framework in this way:

First I have the view file where I've declared the component in this way:

render.js from one component

<my-component><!-- # include virtual="/my-path" --></my-component>

Then, in another file (in another component) I'm receiving a request like this:

server.js from another component.

app.get('/my-path', (req, res) => {
  res.send(render())
}

Where render() method return an html, for example <div>hello</div>.

And my-component is not rended by default:
my-component.js

class WebComponent extends HTMLElement{

    connectedCallback() {
        console.log('connected component');
    }

}
export default WebComponent;

Here, my expected workflow is:

  1. Load the view (render.js).
  2. my-component call /my-path because the <!-- # include virtual="/my-path" -->
  3. The component is 'filled' with /my-path returned HTML.
  4. View the web component rendered by the server into client.

But it is not working, the component is not rendered and is empty.

I have tested accessing into http://localhost:XXXX/my-path and the browser output the result correctly.

Also, the custom component display the message into console.log('connected component');, so the component exists and starts.

But the path my-path is not called... why? Have I missed something or am I mistaken?. Maybe I need render the web component, but then this is not SSI rendering from the server?

Also I've manually trigger my-path route in the server to check if need to be called but it doesn't work either.

Edit: I'm gonna edit to explain better:

I load web component in server side (or I think I do) in this way:

  1. Build and create a page.js file
  2. Into layout using <script src="/my-path/page.js"></script>
  3. In server.js using: app.use('/my-path', express.static('./build'));

Thanks in advance.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The component will only work on the frontend. If it want to make a request to a certain path and use that response as the body of the element, then you can do that on the frontend.

Give your component a path attribute. This should be the URL to get the data from. Whenever your component has this attribute with a value it will try to get data from that path and set it as it's innerHTML.

<my-component path="/my-path"></my-component>

Using the observedAttributes and attributeChangedCallback methods will enable you to get new data on the first render and whenever the value of the path attribute is changed.

Load this component in your page. When it is rendered on the frontend it will fetch data from the value in the path attribute and set it as it's innerHTML value (as long as the request is successful).

class MyComponent extends HTMLElement {
  static get observedAttributes() {
    return ['path'];
  }

  constructor() {
    super();
  }

  get path() {    
    return this.getAttribute('path');
  }

  set path(value) {
    this.setAttribute('path', value);
  }

  async fetchPath() {
    if (!this.path) {
      return;
    }

    try {
      const response = await fetch(this.path);
      const html = await response.text();
      this.innerHTML = html;
    } catch (error) {
      console.log(error)
    }
  }

  attributeChangedCallback(attrName, oldValue, newValue) {
    if (attrName === 'path') {
      this.fetchPath();
    }
  }
}

customElements.define('my-component', MyComponent);

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to MLink Developer Q&A Community for programmer and developer-Open, Learning and Share
...