Angular 5登录后展示消息功能实现求助
解决你的Angular 5消息发布与展示问题
嘿,我仔细看了你的代码,能发现几个关键问题导致功能没法正常运行,咱们一步步来梳理和修复:
首先,修复NewsLetterComponent里的小问题
你的onclick方法里有一行无效代码,而且表单提交会默认刷新页面,这会直接打断事件传递:
- 组件代码里,去掉无效的
this.newsText;,同时注入我们后面要创建的共享服务:
export class NewsLetterComponent implements OnInit { newsText: string; constructor(private _router: Router, private newsService: NewsService) { } ngOnInit() { this.newsText = null; } onclick(newsText: string) { this.newsText = newsText; // 可选:存本地值用于回显 this.newsService.updateNews(newsText); // 改用服务传递消息 this._router.navigate(['/home']); // 可选:提交后跳转到首页 } }
- HTML里把按钮的
type="submit"改成type="button",阻止默认表单刷新行为:
<div class="container-fluid" > <form> <div class="form-group"> <textarea #newsText class="form-control" rows="3"></textarea> </div> <button type="button" (click)="onclick(newsText.value)" class="btn btn-primary pull-right">Publish</button> </form> </div>
核心问题:缺少全局数据共享服务
你的思路是对的,但组件间直接用@Input/@Output只能处理直接父子关系,而管理员页面和首页大概率不是这种关系,而且用户登录后要保留消息,必须用全局服务+可选持久化来实现:
1. 创建NewsService共享服务
这个服务负责存储和传递消息,还能把消息存在本地存储里,确保用户刷新或重新登录后还能看到:
import { Injectable } from '@angular/core'; import { BehaviorSubject } from 'rxjs/BehaviorSubject'; @Injectable() export class NewsService { // 使用BehaviorSubject保存消息,能给新订阅者发送最新值 private newsSubject = new BehaviorSubject<string>(null); currentNews = this.newsSubject.asObservable(); // 更新消息的方法 updateNews(news: string) { this.newsSubject.next(news); // 存到localStorage,实现持久化 localStorage.setItem('adminNews', news); } // 获取本地存储的消息(用户登录后调用) getSavedNews() { const savedNews = localStorage.getItem('adminNews'); if (savedNews) { this.newsSubject.next(savedNews); } } }
记得在AppModule的providers数组里注册这个服务,让整个应用都能使用:
@NgModule({ // ...其他配置项 providers: [NewsService] }) export class AppModule { }
2. 首页组件接收消息
在展示消息的首页组件里,注入服务并订阅消息:
export class HomeComponent implements OnInit { newsletterText: any[] = []; // 要初始化数组,避免push报错 constructor(private newsService: NewsService) { } ngOnInit() { // 页面加载时先获取本地存储的消息 this.newsService.getSavedNews(); // 订阅消息变化,更新展示内容 this.newsService.currentNews.subscribe(news => { if (news) { this.newsletterText = [{ severity: 'info', summary: news }]; } }); } }
对应的首页HTML保持简洁,绑定到组件的newsletterText:
<header [user]="user" (logout)="logout()"> Loading...</header> <p-messages [(value)]="newsletterText"></p-messages> <content class="admin-page"> <sidenav></sidenav> <router-outlet></router-outlet> </content>
修正AdminPageComponent的问题
你之前的@ViewChild拼写错误(newsletterComponenet应为newsletterComponent),而且没必要用@ViewChild,直接在AdminPage的模板里引入NewsLetterComponent即可:
<!-- AdminPage的模板里添加这个组件 --> <app-news-letter></app-news-letter> <!-- 其他原有代码 --> <header [user]="user" (logout)="logout()"> Loading...</header> <p-messages [(value)]="newsletterText"></p-messages> <content class="admin-page"> <sidenav></sidenav> <router-outlet></router-outlet> </content>
如果需要在AdminPage也展示消息,同样注入NewsService订阅即可,无用的@Input和ngOnChanges可以直接删掉。
总结
你的核心思路是完全正确的:管理员提交消息,用户登录后首页展示。只是缺少了全局共享数据的服务,还有一些代码细节(比如表单默认行为、拼写错误)需要修正。按照上面的步骤修改后,功能应该就能正常运行了。
内容的提问来源于stack exchange,提问作者CarlaDX
相关产品推荐
相关产品推荐

