如何从Node Express渲染Angular组件

5

我正在使用GET请求访问以下URL:http://localhost:5029/article/16

在Node中,我检查article/16的方式如下:

req.url.split("article/")[1];

并尝试使用handlebars渲染组件,代码如下:

res.render('header', {layout: 'header.component.html'});

我看到组件被渲染出来了,但是CSS样式没有加载。

我的component.ts文件如下:

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

组件 HTML:

<div class="header">
  <li class="menu-item">
    <a [routerLinkActive]="['active']" routerLink="/home">Home</a>
  </li>
  <li class="menu-item">
    <div class="dropdown">
      <button type="button" class="btn dropdown-toggle" data-toggle="dropdown" [routerLinkActive]="['active']">Tutorials</button>
    </div>
  </li>
</div>

Handlebars设置:

app.engine(
  "hbs",
  hbs({
    extname: "html",
    defaultView: "default",
    layoutsDir:  "../src/app/components/header/",
    partialsDir: "../src/app/components/"
  })
);

app.set("view engine", "hbs");

RiotJS已经实现了类似的要求:

https://riot.js.org/api/#-riotrendertagname-opts

// render "my-tag" to html
var mytag = require('my-tag')
riot.render(mytag, { foo: 'bar' })

你需要在运行时编译这些吗?你可以查看Angular Universal项目,它应该能够解释如何实现。 - Rafael
@Rafael 无论是在运行时还是AOT编译时,我都需要在进行GET请求时进行渲染。 - kittu
2
你正在要求你的Handlebars渲染器来渲染一个Angular模板,这是不可能的。 你需要使用Angular Universal。 或者请求你的服务器返回整个模块,并让Angular在运行时进行渲染。 - Milad
@Milad 我并没有说handlebars应该渲染它。那只是我尝试的一个例子。我正在寻找一种在运行时渲染angular组件的方法。我不确定是否可以通过angular universal实现,因为我只想渲染特定组件,而不是整个应用程序。 - kittu
@kittu,我明白了,也许你应该将组件分离成独立的应用程序,并让 Universal 渲染它们。 但是,你的使用场景是什么?也许我们可以提出其他建议。 唯一需要在运行时渲染组件的原因是为了 SEO,我猜。 - Milad
@Milad 是的,只是为了SEO,但我不想使用Angular Universal加载所有组件,因为像documentlocalstorage等东西在服务器上不可用。所以我只想从服务器呈现特定的组件。 - kittu
1个回答

3

不确定为什么您想要从Node Express渲染特定的Angular组件,但我将尝试解释组件是什么以及为什么您不能直接加载它们,以及同样更好的替代方法。

可能您已经知道,装饰器使特定的代码块区别于服务、组件、指令等。

装饰器是使用前缀@符号立即跟随类、参数、方法或属性调用的函数。

例如:

@Component({
})
export class TestComponent {}

@Injectable()
export class TestService {}

注意@Component或@Injectable上的()。这些装饰器需要在某个ngModule中注册。
这意味着@ Component会在JavaScript遇到@ Component()时被调用一次。反过来,这意味着必须有一个Component函数返回与上面概述的装饰器签名之一匹配的函数。这是装饰器工厂模式的一个例子。
在应用程序启动期间,所有这些函数都将被调用,并且编译器将ts代码转换为vanilla js,在浏览器中执行。
回到你想要尝试的问题,那就是尝试不使用TS编译器加载组件。(在幕后,构建或编译应用程序时,angular正在为我们做很多工作)
如果您不想通过angular帮助服务所有组件,则可以使用Angular Element( Angular元素是打包为自定义元素的Angular组件, 是定义框架无关的新HTML元素的Web标准), 这可以在任何页面上直接呈现而无需使用angular。
如欲了解更多,请访问https://angular.io/guide/elements。
希望这能有所帮助,一切顺利!

在服务器端使用Webpack,手动编译Angular组件(从ts到js)是否可能进行AOT编译? - kittu
您可以创建一个 Angular 元素(组件),它可以独立编译,并且可以通过在任何项目中导入相同的元素作为 Web 元素来使用。(React、vanilla js 等) - Akshay Rajput

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