Angular 6 + 路由解析器 = 生产中的 404 页面
Angular 6 + Routes Resolver = 404 page in production
我是 Angular 社区的新成员,来自 rails;我在一个网站上工作,在那里我可以 post 我的客户网站的案例研究。到目前为止,我很喜欢 angular 但我正在 运行 陷入一个让我有点担心的问题。我似乎无法使用超链接来引用任何项目的问题。例如,如果您单击 this the application will return a 404 status but if you start from the root page 一切都会 运行 没问题。
我试过的解决方法
- 在加载之前向路由添加解析器以获取数据
页;它有效,但仍然没有超链接。
谁能帮我弄清楚我遗漏了什么或做错了什么;
下面是我的代码;任何帮助将不胜感激
- Project.service.ts
import { AngularFirestore } from 'angularfire2/firestore';
import { Observable, of } from 'rxjs';
import { map, } from 'rxjs/operators';
import { Injectable } from '@angular/core';
import { Project } from '../../models/project';
import { HttpClient } from '@angular/common/http';
import { Post } from '../post';
@Injectable()
export class ProjectService {
ProjectListRef: Observable<any[]>;
featuredProjectList: Observable<any[]>;
posts: Array<Post>;
constructor( private database: AngularFirestore, private http: HttpClient) {
// Link For All Projects Page
const allProjectsListLink = this.database.collection<Project>('projects', ref => ref.orderBy('company_name'));
// Link For Featured Project Page
const featuredProjectsListLink = this.database.collection<Project>('projects', ref => ref.limit(5));
this.ProjectListRef = allProjectsListLink.snapshotChanges()
// using map pipe
.pipe(map( actions => {
return actions.map(a => {
// Get Document Data
const data = a.payload.doc.data() as Project;
// Get Document Id
const id = a.payload.doc.id;
return {id, ...data};
});
}));
this.featuredProjectList = featuredProjectsListLink.snapshotChanges()
// using map pipe
.pipe(map( actions => {
return actions.map(a => {
// Get Document Data
const data = a.payload.doc.data() as Project;
// Get Document Id
const id = a.payload.doc.id;
return {id, ...data};
});
}));
}
getAllProjects() {
return this.ProjectListRef;
}
getFeaturedProjects() {
return this.featuredProjectList;
}
getProject(id: string) {
console.log(id);
return this.database.collection('projects').doc(id)
.ref.get().then( doc => doc.data() );
}
}
- Project.component.ts
import { Component, OnInit, Injectable, Inject } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { tap } from 'rxjs/operators';
import { ProjectService } from '../../app/services/project.service';
import { AngularFirestore } from 'angularfire2/firestore';
import { Project } from '../../models/project';
import { DOCUMENT } from '@angular/common';
@Injectable()
@Component({
selector: 'app-project-page',
templateUrl: './project-page.component.html',
styleUrls: ['./project-page.component.scss']
})
export class ProjectPageComponent implements OnInit {
project: Project;
projectId: any;
projectRef: any;
constructor(@Inject(DOCUMENT) private document: any, private router: Router,
private route: ActivatedRoute,
public database: AngularFirestore,
private projectService: ProjectService
) {
}
ngOnInit() {
// print out the data from the route resolver
this.route.data.pipe(
tap(console.log))
.subscribe(
data => this.project = data['project']
);
}
goToWebsite(url) {
this.document.location.href = url;
}
}
3. **ProjectResolver.ts**
import { ProjectService } from './../../app/services/project.service';
import { Project } from './../project';
import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs';
import { Injectable } from '@angular/core';
@Injectable()
export class ProjectResolver implements Resolve<Project> {
constructor(private projectService: ProjectService) {
}
resolve(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<Project>|Promise<any> {
return this.projectService.getProject(route.params['id']);
}
}
- 申请途径
import { AddLeadPageComponent } from './add-lead-page/add-lead-page.component';
import { GoogleAdsPageComponent } from './google-ads-page/google-ads-page.component';
import { WebAppsPageComponent } from './web-apps-page/web-apps-page.component';
import { BrandedWebsitesPageComponent } from './branded-websites-page/branded-websites-page.component';
import { ServiceOverviewPageComponent } from './service-overview-page/service-overview-page.component';
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { HomePageComponent } from './home-page/home-page.component';
import { AboutPageComponent } from './about-page/about-page.component';
import { BlogPageComponent } from './blog-page/blog-page.component';
import { WebServicesPageComponent } from './web-services-page/web-services-page.component';
import { SEMPageComponent } from './sempage/sempage.component';
import { ContactPageComponent } from './contact-page/contact-page.component';
import { AllProjectsPageComponent } from './all-projects-page/all-projects-page.component';
import { ResearchServicePageComponent } from './research-service-page/research-service-page.component';
import { ProjectPageComponent } from './project-page/project-page.component';
import { TeamPageComponent } from './team-page/team-page.component';
import { NewProjectComponent } from './new-project/new-project.component';
import { DigitalMarketingPageComponent } from './digital-marketing-page/digital-marketing-page.component';
import { ProjectResolver } from '../models/resolvers/project.resolver';
const routes: Routes = [
{ path: '', redirectTo: '/home', pathMatch: 'full' },
{ path: 'home', component: HomePageComponent},
{ path: 'about', component: AboutPageComponent},
{ path: 'blog', component: BlogPageComponent},
{ path: 'team', component: TeamPageComponent},
{ path: 'portfolio', component: AllProjectsPageComponent},
{ path: 'services', component: ServiceOverviewPageComponent},
{ path: 'project/:id', component: ProjectPageComponent, resolve: { project: ProjectResolver}},
{ path: 'brand-strategy', component: ResearchServicePageComponent},
{ path: 'digital-strategy', component: DigitalMarketingPageComponent},
{ path: 'custom-websites', component: BrandedWebsitesPageComponent},
{ path: 'web-apps', component: WebAppsPageComponent},
{ path: 'google-ads', component: GoogleAdsPageComponent},
{ path: 'web-design-development', component: WebServicesPageComponent},
{ path: 'search-engine-marketing', component: SEMPageComponent},
{ path: 'start-new-project', component: ContactPageComponent},
{ path: 'new-project', component: NewProjectComponent},
// post trial
{ path: 'posts/add', component: AddLeadPageComponent},
{ path: 'posts/add/:id', component: AddLeadPageComponent},
];
@NgModule({
imports: [
RouterModule.forRoot(routes, { scrollPositionRestoration: 'enabled'})
],
exports: [RouterModule]
})
export class AppRoutingModule { }
您的 angular 代码没有任何错误。您面临的问题是 url 没有被重写为 index.html。您需要在您的 Firebase 设置中配置它 (firebase.json)。这是最简单和最常见的配置:
"hosting": {
"public": "dist",
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
}
}
我是 Angular 社区的新成员,来自 rails;我在一个网站上工作,在那里我可以 post 我的客户网站的案例研究。到目前为止,我很喜欢 angular 但我正在 运行 陷入一个让我有点担心的问题。我似乎无法使用超链接来引用任何项目的问题。例如,如果您单击 this the application will return a 404 status but if you start from the root page 一切都会 运行 没问题。
我试过的解决方法
- 在加载之前向路由添加解析器以获取数据 页;它有效,但仍然没有超链接。
谁能帮我弄清楚我遗漏了什么或做错了什么;
下面是我的代码;任何帮助将不胜感激
- Project.service.ts
import { AngularFirestore } from 'angularfire2/firestore';
import { Observable, of } from 'rxjs';
import { map, } from 'rxjs/operators';
import { Injectable } from '@angular/core';
import { Project } from '../../models/project';
import { HttpClient } from '@angular/common/http';
import { Post } from '../post';
@Injectable()
export class ProjectService {
ProjectListRef: Observable<any[]>;
featuredProjectList: Observable<any[]>;
posts: Array<Post>;
constructor( private database: AngularFirestore, private http: HttpClient) {
// Link For All Projects Page
const allProjectsListLink = this.database.collection<Project>('projects', ref => ref.orderBy('company_name'));
// Link For Featured Project Page
const featuredProjectsListLink = this.database.collection<Project>('projects', ref => ref.limit(5));
this.ProjectListRef = allProjectsListLink.snapshotChanges()
// using map pipe
.pipe(map( actions => {
return actions.map(a => {
// Get Document Data
const data = a.payload.doc.data() as Project;
// Get Document Id
const id = a.payload.doc.id;
return {id, ...data};
});
}));
this.featuredProjectList = featuredProjectsListLink.snapshotChanges()
// using map pipe
.pipe(map( actions => {
return actions.map(a => {
// Get Document Data
const data = a.payload.doc.data() as Project;
// Get Document Id
const id = a.payload.doc.id;
return {id, ...data};
});
}));
}
getAllProjects() {
return this.ProjectListRef;
}
getFeaturedProjects() {
return this.featuredProjectList;
}
getProject(id: string) {
console.log(id);
return this.database.collection('projects').doc(id)
.ref.get().then( doc => doc.data() );
}
}
- Project.component.ts
import { Component, OnInit, Injectable, Inject } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { tap } from 'rxjs/operators';
import { ProjectService } from '../../app/services/project.service';
import { AngularFirestore } from 'angularfire2/firestore';
import { Project } from '../../models/project';
import { DOCUMENT } from '@angular/common';
@Injectable()
@Component({
selector: 'app-project-page',
templateUrl: './project-page.component.html',
styleUrls: ['./project-page.component.scss']
})
export class ProjectPageComponent implements OnInit {
project: Project;
projectId: any;
projectRef: any;
constructor(@Inject(DOCUMENT) private document: any, private router: Router,
private route: ActivatedRoute,
public database: AngularFirestore,
private projectService: ProjectService
) {
}
ngOnInit() {
// print out the data from the route resolver
this.route.data.pipe(
tap(console.log))
.subscribe(
data => this.project = data['project']
);
}
goToWebsite(url) {
this.document.location.href = url;
}
}
3. **ProjectResolver.ts**
import { ProjectService } from './../../app/services/project.service';
import { Project } from './../project';
import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs';
import { Injectable } from '@angular/core';
@Injectable()
export class ProjectResolver implements Resolve<Project> {
constructor(private projectService: ProjectService) {
}
resolve(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<Project>|Promise<any> {
return this.projectService.getProject(route.params['id']);
}
}
- 申请途径
import { AddLeadPageComponent } from './add-lead-page/add-lead-page.component';
import { GoogleAdsPageComponent } from './google-ads-page/google-ads-page.component';
import { WebAppsPageComponent } from './web-apps-page/web-apps-page.component';
import { BrandedWebsitesPageComponent } from './branded-websites-page/branded-websites-page.component';
import { ServiceOverviewPageComponent } from './service-overview-page/service-overview-page.component';
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { HomePageComponent } from './home-page/home-page.component';
import { AboutPageComponent } from './about-page/about-page.component';
import { BlogPageComponent } from './blog-page/blog-page.component';
import { WebServicesPageComponent } from './web-services-page/web-services-page.component';
import { SEMPageComponent } from './sempage/sempage.component';
import { ContactPageComponent } from './contact-page/contact-page.component';
import { AllProjectsPageComponent } from './all-projects-page/all-projects-page.component';
import { ResearchServicePageComponent } from './research-service-page/research-service-page.component';
import { ProjectPageComponent } from './project-page/project-page.component';
import { TeamPageComponent } from './team-page/team-page.component';
import { NewProjectComponent } from './new-project/new-project.component';
import { DigitalMarketingPageComponent } from './digital-marketing-page/digital-marketing-page.component';
import { ProjectResolver } from '../models/resolvers/project.resolver';
const routes: Routes = [
{ path: '', redirectTo: '/home', pathMatch: 'full' },
{ path: 'home', component: HomePageComponent},
{ path: 'about', component: AboutPageComponent},
{ path: 'blog', component: BlogPageComponent},
{ path: 'team', component: TeamPageComponent},
{ path: 'portfolio', component: AllProjectsPageComponent},
{ path: 'services', component: ServiceOverviewPageComponent},
{ path: 'project/:id', component: ProjectPageComponent, resolve: { project: ProjectResolver}},
{ path: 'brand-strategy', component: ResearchServicePageComponent},
{ path: 'digital-strategy', component: DigitalMarketingPageComponent},
{ path: 'custom-websites', component: BrandedWebsitesPageComponent},
{ path: 'web-apps', component: WebAppsPageComponent},
{ path: 'google-ads', component: GoogleAdsPageComponent},
{ path: 'web-design-development', component: WebServicesPageComponent},
{ path: 'search-engine-marketing', component: SEMPageComponent},
{ path: 'start-new-project', component: ContactPageComponent},
{ path: 'new-project', component: NewProjectComponent},
// post trial
{ path: 'posts/add', component: AddLeadPageComponent},
{ path: 'posts/add/:id', component: AddLeadPageComponent},
];
@NgModule({
imports: [
RouterModule.forRoot(routes, { scrollPositionRestoration: 'enabled'})
],
exports: [RouterModule]
})
export class AppRoutingModule { }
您的 angular 代码没有任何错误。您面临的问题是 url 没有被重写为 index.html。您需要在您的 Firebase 设置中配置它 (firebase.json)。这是最简单和最常见的配置:
"hosting": {
"public": "dist",
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
}
}