2

We have, unfortunately a multi page application that we've been running with AngularJS. Now we're trying to migrate to Angular, as LTS approaches. We used to populate some part of our templates with the server data, rendering html as follows:

<div class="some-class" ng-controller="SomeCtrl as ctrl">
    <div>...</div> <!-- Render some data from server -->
    <div sec:authorize="isRememberMe()">...</div> <!-- Use some Thymeleaf security tags -->
</div>

However, now that the components are already on the client, I'm looking for ways to manipulate templates with html rendered by the server. I've tried with ng-content which is useful for some cases, where I can bootstrap the component itself outside app-root like Render Angular component outside the main app. But when the template is in component itself, this ability is gone as well.

An alternative would be rendering the page as a non-Angular, conventional html page (not a component), and accessing some basic functionality that could be provided by Angular. The approach we used in the past as well allowed this, but I have no idea how I could achieve this.

Is there a walkaround for what I'm looking for?

georgeawg
  • 48,608
  • 13
  • 72
  • 95
Hasan Can Saral
  • 2,950
  • 5
  • 43
  • 78
  • Are you making HTTP calls from angular to server to get the data in the new implementation? – subodhkalika Feb 09 '21 at 08:47
  • Yes, but for some parts, I cannot make RESTful requests. Like `sec:authorize="isRememberMe()"`. – Hasan Can Saral Feb 09 '21 at 08:49
  • Do you want to modify the HTML received from the server or display as it is ? – subodhkalika Feb 09 '21 at 09:00
  • I want to render the HTML, and use JS/TS functionality in Component. – Hasan Can Saral Feb 09 '21 at 09:00
  • Is it possible for you to bring the entire HTML being rendered by server on the client side and make HTTP calls to get the necessary data and populate it on the client side. This can give you quite a lot flexibility. **Make child component for that particular part. – subodhkalika Feb 09 '21 at 09:03
  • It is not possible, the whole question is about it... – Hasan Can Saral Feb 09 '21 at 09:10
  • I see. I can suggest you to go through these thread. https://stackoverflow.com/questions/31548311/angular-html-binding Another is https://stackoverflow.com/questions/38888008/how-can-i-use-create-dynamic-template-to-compile-dynamic-component-with-angular – subodhkalika Feb 09 '21 at 09:16
  • Markup added at runtime won't be processed by Angular. This comment has explained and provided useful reads for your case. I hope its helpful. https://stackoverflow.com/a/41089093/6682406 – subodhkalika Feb 09 '21 at 09:20

1 Answers1

0

Here's what I come up with:

Render the index.html with Thymeleaf as follows:

<!DOCTYPE html>
<html lang="en"
      xmlns:th="http://www.thymeleaf.org">
<head th:replace="partials/head :: head"></head>
<body>
    <th:block th:replace="partials/header :: header"></th:block>
    <app-root th:attr="some-property=${some.value.from.model}"></app-root>
    <th:block th:replace="partials/footer :: footer"></th:block>
</body>

This will render:

<!DOCTYPE html>
<html lang="en"
      xmlns:th="http://www.thymeleaf.org">
<head>
    ...
</head>
<body>
    ...
    <app-root some-property="some-value"></app-root>
    ...
</body>

Create a data.service.ts:

  appData: any = {};

And in app.component.ts:

constructor(private dataService: DataService,
            private element: ElementRef) {
}

ngOnInit(): void {
    this.dataService.appData['some-property'] = this.element.nativeElement.getAttribute('some-property');
}

Finally in sub.component.ts:

constructor(private dataService: DataService) {
}

ngOnInit(): void {
    this.someProperty = this.dataService.appData['some-property'];
}
Hasan Can Saral
  • 2,950
  • 5
  • 43
  • 78