具有来自 Web 服务的动态元数据的 Angular 6 元服务
Posted
技术标签:
【中文标题】具有来自 Web 服务的动态元数据的 Angular 6 元服务【英文标题】:Angular 6 Meta service with dynamic metadata from web service 【发布时间】:2019-03-05 16:22:06 【问题描述】:我正在尝试使用从 Web 服务检索到的数据来更新 Angular 6(更新:现在是 Angular 7)通用应用程序(使用 Meta 和 Title)中的元数据。我专门为 Twitter 和 Facebook 卡片执行此操作。我知道他们的爬虫不执行 javascript,这就是我使用 Angular Universal 在服务器端设置元数据的原因。我正在使用Facebook Sharing debugger tool 来检查结果。
我尝试了几种不同的方法,并查找了示例,但我还没有找到在设置元数据之前从对 Web 服务的异步调用中检索数据的方法。 (请注意,我在 Angular Universal 4 应用程序中成功将此服务与 Web 服务一起使用。)
使用下面的代码,“og:url”标签被正确设置,因为它不需要网络服务调用来获取数据。但是,标题设置不正确。如果我将“setTitle”调用移动到 ngOnInit 并提供一个字符串,那么它会起作用——但从 Web 服务获取数据却不起作用。
我尝试使用服务来收集数据,然后设置元数据,但这也不起作用。我从解析器获取数据,但它不能解决 Facebook/Twitter 问题。
ngOnInit()
const metaUrl = 'https://www.test.com' + this._router.url;
this._metaService.updateTag( property: 'og:url', content: metaUrl );
this._sub = this._route.params.subscribe(params =>
const code = params['person'];
this.getInfo(code);
);
getInfo(code: string)
this._myWebService.getPerson(code).subscribe(
data =>
this._person = data;
// set dynamic metadata
const metaTitle = this._person.name + ' | site description';
this._titleService.setTitle(metaTitle);
this._metaService.updateTag( name: 'twitter:title', content: metaTitle );
);
更新:我还尝试使用解析器首先获取数据,以便我可以在 onInit 中使用它。它不工作。
path: 'view/:person', component: ViewComponent,
resolve: person: ViewResolver , data: person: ViewResolver
然后在onInit中:
const data: any = this._routeActive.snapshot.data;
this.metaTitle = data.person.value.name;
this._metaService.updateTag(property: 'og:title', content: this.metaTitle );
this._metaService.updateTag(name: 'twitter:title', content: this.metaTitle );
【问题讨论】:
您是否检查过代码执行是否通过getInfo
服务器端?
是的,我检查了服务器呈现的页面,一切都很好,包括源代码中的元标记。但是,当我将应用程序部署到 Google App Engine 时,Facebook 调试工具看不到更新的元标记。我什至添加了一个解析器来首先获取数据,但它仍然无法正常工作。
Angular Universal 一定有问题,因为提供的代码看起来不错。当 ngZone 中没有更多事情可做时,AU 停止渲染,也许 API 调用在 ngZone 之外运行?会不会是连接问题?也许 API 调用的 observable 返回一个错误,这可以提供更多信息。 AU 服务器在本地工作吗?您可以在本地计算机上轻松检查输出字符串。 :thinking: :thinking:
我同意你的评价。我在本地检查过,服务器端页面是正确的(即正确的标签在源代码中)。关于如何在 prod 环境中调试它的任何建议?也许我应该将 s-s-r 页面设置为不同的端口并以这种方式进行检查?谢谢!
我建议创建一个服务,作为对 s-s-r 应用程序的依赖注入。这样您首先完全在服务器端创建并填写该服务,然后将所有数据传递给 s-s-r 应用程序的render
。渲染时很难控制异步调用,所以我们发现一个好的做法是提前解析所有数据,并通过render
传递尽可能少的额外作业。如果仍然有兴趣,我可以向您展示示例。
【参考方案1】:
我找到了解决方案。在确定这一定不是代码问题后,我去了Angular Universal starter repo 并更新了我的配置(例如,tsconfig.json、angular.json 等),直到它起作用。我的项目已经升级了几次,我还没有复制初始存储库中的所有更改。
【讨论】:
以上是关于具有来自 Web 服务的动态元数据的 Angular 6 元服务的主要内容,如果未能解决你的问题,请参考以下文章
JavaEE基础(01):Servlet实现方式,生命周期执行过程