Angular实现75%滚动触发单条文章加载及路由显示文章ID
Hey there! Let's tweak your Angular infinite scroll setup to match your exact needs—loading only the first post initially, triggering the next one at 75% scroll, and showing the post ID in the URL. Here's a step-by-step breakdown of the changes:
1. Adjust the News Service to Fetch Single Posts
First, we need to ensure each API call returns exactly one post (instead of multiple). Update your news.service.ts to add the per_page=1 parameter:
import { Injectable } from '@angular/core'; import { Http } from '@angular/http'; const BASE_URL = 'https://www.eremnews.com/wp-json/wp/v2/posts?minified=true'; @Injectable() export class NewsService { constructor(private http: Http) { } getLatestStories(page: number = 1) { // Add per_page=1 to fetch one post per request return this.http.get(`${BASE_URL}/news?page=${page}&per_page=1`); } }
2. Update the App Component for Controlled Loading
Modify app.component.ts to handle initial single-post loading, route updates, and adjust the scroll callback logic:
import { Component, OnInit } from '@angular/core'; import { Response } from '@angular/http'; import { Observable } from 'rxjs/Observable'; import { NewsService } from './news.service'; import { Router } from '@angular/router'; // Import Router for URL updates import 'rxjs/add/operator/do'; @Component({ selector: 'app-root', styleUrls: ['./app.component.css'], templateUrl: './app.component.html', providers: [NewsService] }) export class AppComponent implements OnInit { currentPage: number = 1; news: Array<any> = []; scrollCallback; constructor(private newsService: NewsService, private router: Router) { this.scrollCallback = this.getStories.bind(this); } ngOnInit() { // Manually load the FIRST post when the component initializes this.getStories().subscribe(); } getStories() { return this.newsService.getLatestStories(this.currentPage) .do(this.processData); } private processData = (response: Response) => { const newPost = response.json()[0]; // Extract the single post from the response this.news.push(newPost); this.currentPage++; // Update the URL to show the latest post's ID this.router.navigate(['/', newPost.id]); console.log(this.news); } }
3. Fix the Template for Scroll Trigger and Content Rendering
Update app.component.html to set the 75% scroll trigger, disable immediate full data load, and fix content rendering (remove unnecessary | json pipes):
<ul id="infinite-scroller" appInfiniteScroller scrollPercent="75" immediateCallback="false" [scrollCallback]="scrollCallback"> <li *ngFor="let x of news"> <h1>{{x.title.rendered}}</h1> <br> <figure style="padding:20px"> <img [src]="x.post_thumbnail.thumbnail" alt="{{x.title.rendered}}"> </figure> <div class="details"> <!-- Use innerHTML to render raw HTML content correctly --> <p [innerHTML]="x.content.rendered"></p><br> </div> <p>{{x.date_gmt_lang}}</p> </li> </ul>
4. Add Routing to Display Post ID in URL
Create an app-routing.module.ts to configure route parameters for post IDs:
import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; import { AppComponent } from './app.component'; const routes: Routes = [ { path: '', component: AppComponent }, { path: ':id', component: AppComponent } // Route to show post ID in URL ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { }
Then import this routing module into your app.module.ts:
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { HttpModule } from '@angular/http'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import { NavBarComponent } from './navbar.component'; import { NewsService } from './news.service'; import { InfiniteScrollerDirective } from './infinite-scroller.directive'; // Ensure your directive is declared @NgModule({ declarations: [ AppComponent, NavBarComponent, InfiniteScrollerDirective ], imports: [ BrowserModule, HttpModule, AppRoutingModule ], providers: [NewsService], bootstrap: [AppComponent] }) export class AppModule { }
Key Changes Explained:
- Single Post Loading: The
per_page=1parameter ensures each API call fetches only one post, matching your "load one at a time" requirement. - Initial Load Control: We manually load the first post in
ngOnInit()and setimmediateCallback="false"to prevent the directive from loading all posts upfront. - 75% Scroll Trigger: Updated
scrollPercent="75"to trigger the next load when the user reaches 75% of the page height. - URL Updates: Added routing to display the latest post's ID in the URL using Angular's
Routerservice. - Content Rendering: Removed
| jsonpipes (which were showing raw JSON strings) and used[innerHTML]to properly render HTML content from the API.
内容的提问来源于stack exchange,提问作者Arpita Soni

