যখন আমি কৌনিক 2 তে কোনও রুট পরিবর্তন করি তখন আমি কীভাবে লোডিং স্ক্রিনটি দেখাব?
যখন আমি কৌনিক 2 তে কোনও রুট পরিবর্তন করি তখন আমি কীভাবে লোডিং স্ক্রিনটি দেখাব?
উত্তর:
বর্তমান কৌণিক রাউটার নেভিগেশন ইভেন্টগুলি সরবরাহ করে। আপনি এগুলিতে সাবস্ক্রাইব করতে পারেন এবং সেই অনুযায়ী ইউআই পরিবর্তন করতে পারেন। যেমন অন্যান্য ঘটনা গণনা করতে মনে রাখুন NavigationCancel
এবং NavigationError
ক্ষেত্রে আপনার স্পিনার থামাতে রাউটার ট্রানজিশন ব্যর্থ হয়।
app.componal.ts - আপনার মূল উপাদান
...
import {
Router,
// import as RouterEvent to avoid confusion with the DOM Event
Event as RouterEvent,
NavigationStart,
NavigationEnd,
NavigationCancel,
NavigationError
} from '@angular/router'
@Component({})
export class AppComponent {
// Sets initial value to true to show loading spinner on first load
loading = true
constructor(private router: Router) {
this.router.events.subscribe((e : RouterEvent) => {
this.navigationInterceptor(e);
})
}
// Shows and hides the loading spinner during RouterEvent changes
navigationInterceptor(event: RouterEvent): void {
if (event instanceof NavigationStart) {
this.loading = true
}
if (event instanceof NavigationEnd) {
this.loading = false
}
// Set loading state to false in both of the below events to hide the spinner in case a request fails
if (event instanceof NavigationCancel) {
this.loading = false
}
if (event instanceof NavigationError) {
this.loading = false
}
}
}
app.componal.html - আপনার রুট ভিউ
<div class="loading-overlay" *ngIf="loading">
<!-- show something fancy here, here with Angular 2 Material's loading bar or circle -->
<md-progress-bar mode="indeterminate"></md-progress-bar>
</div>
পারফরম্যান্স উন্নত উত্তর : আপনি যদি আরও ভাল পদ্ধতিতে পারফরম্যান্সের বিষয়ে চিন্তা করেন তবে তা প্রয়োগ করা কিছুটা ক্লান্তিকর তবে পারফরম্যান্সের উন্নতি অতিরিক্ত কাজের জন্য মূল্যবান হবে। *ngIf
শর্তসাপেক্ষে স্পিনারকে দেখাতে ব্যবহার করার পরিবর্তে , আমরা অ্যাংুলারকে লাভবান করতে পারি NgZone
এবং Renderer
স্পিনারকে সরিয়ে / অফ করতে পারি যা স্পিনারের অবস্থা পরিবর্তন করার পরে অ্যাংুলারের পরিবর্তন সনাক্তকরণকে বাইপাস করবে। আমি এই পাওয়া ব্যবহার তুলনায় অ্যানিমেশন বাধামুক্ত করতে *ngIf
অথবা একটি async
নল।
এটি কিছু টুইটের সাথে আমার আগের উত্তরের মতো:
app.componal.ts - আপনার মূল উপাদান
...
import {
Router,
// import as RouterEvent to avoid confusion with the DOM Event
Event as RouterEvent,
NavigationStart,
NavigationEnd,
NavigationCancel,
NavigationError
} from '@angular/router'
import {NgZone, Renderer, ElementRef, ViewChild} from '@angular/core'
@Component({})
export class AppComponent {
// Instead of holding a boolean value for whether the spinner
// should show or not, we store a reference to the spinner element,
// see template snippet below this script
@ViewChild('spinnerElement')
spinnerElement: ElementRef
constructor(private router: Router,
private ngZone: NgZone,
private renderer: Renderer) {
router.events.subscribe(this._navigationInterceptor)
}
// Shows and hides the loading spinner during RouterEvent changes
private _navigationInterceptor(event: RouterEvent): void {
if (event instanceof NavigationStart) {
// We wanna run this function outside of Angular's zone to
// bypass change detection
this.ngZone.runOutsideAngular(() => {
// For simplicity we are going to turn opacity on / off
// you could add/remove a class for more advanced styling
// and enter/leave animation of the spinner
this.renderer.setElementStyle(
this.spinnerElement.nativeElement,
'opacity',
'1'
)
})
}
if (event instanceof NavigationEnd) {
this._hideSpinner()
}
// Set loading state to false in both of the below events to
// hide the spinner in case a request fails
if (event instanceof NavigationCancel) {
this._hideSpinner()
}
if (event instanceof NavigationError) {
this._hideSpinner()
}
}
private _hideSpinner(): void {
// We wanna run this function outside of Angular's zone to
// bypass change detection,
this.ngZone.runOutsideAngular(() => {
// For simplicity we are going to turn opacity on / off
// you could add/remove a class for more advanced styling
// and enter/leave animation of the spinner
this.renderer.setElementStyle(
this.spinnerElement.nativeElement,
'opacity',
'0'
)
})
}
}
app.componal.html - আপনার রুট ভিউ
<div class="loading-overlay" #spinnerElement style="opacity: 0;">
<!-- md-spinner is short for <md-progress-circle mode="indeterminate"></md-progress-circle> -->
<md-spinner></md-spinner>
</div>
router navigation
এবং it triggering the spinner
তারপর না কি এটিকে থামাতে সক্ষম হচ্ছে। navigationInterceptor
সমাধানের মতো মনে হচ্ছে তবে আমি নিশ্চিত নই যে অন্য কিছু ভাঙ্গার অপেক্ষায় আছে কিনা I'm যদি async requests
এটির সাথে মিশে যায় তবে এটি আবার সমস্যাটির পরিচয় দেবে, আমি মনে করি।
display
করতে none
বা এটি ব্যবহার করে পরিবর্তন করেছি inline
।
'md-spinner' is not a known element:
। আমি কৌণিকের কাছে বেশ নতুন। আপনি কি আমাকে বলতে পারেন ভুল হতে পারে?
আপডেট: 3 এখন আমি নতুন রাউটারে আপগ্রেড করেছি, আপনি যদি CanDeactivate
গার্ড ব্যবহার করেন তবে @ বোরিসেল্মেকের দৃষ্টিভঙ্গি কার্যকর হবে না । আমি আমার পুরানো পদ্ধতির অবজ্ঞান করছি, ie:
এই উত্তর
UPDATE2 : নতুন-রাউটার বর্ণন প্রতিশ্রুতি এবং রাউটার ঘটনা উত্তর দ্বারা @borislemke স্পিনার বাস্তবায়ন প্রধান দৃষ্টিভঙ্গি আবরণ বলে মনে হয়, আমি এটা পরীক্ষিত havent't কিন্তু আমি এটা সুপারিশ।
আপডেট 1: আমি এই উত্তরটি লিখেছিলাম সেই যুগে Old-Router
, যখন কেবলমাত্র একটি ইভেন্টের route-changed
মাধ্যমে জানানো হত router.subscribe()
। আমি নীচের পদ্ধতির ওভারলোডও অনুভব করেছি এবং এটি ব্যবহার করেই চেষ্টা করার চেষ্টা করেছি router.subscribe()
এবং এটি সনাক্তকরণের কোনও উপায় না থাকায় এটি ব্যাকফায়ার হয়েছিল canceled navigation
। সুতরাং আমাকে দীর্ঘ পদ্ধতির (ডাবল ওয়ার্ক) ফিরে যেতে হয়েছিল।
যদি আপনি Angular2 এ নিজের পথটি জানেন তবে আপনার যা প্রয়োজন তা এটি
Boot.ts
import {bootstrap} from '@angular/platform-browser-dynamic';
import {MyApp} from 'path/to/MyApp-Component';
import { SpinnerService} from 'path/to/spinner-service';
bootstrap(MyApp, [SpinnerService]);
রুট উপাদান- (মাই অ্যাপ)
import { Component } from '@angular/core';
import { SpinnerComponent} from 'path/to/spinner-component';
@Component({
selector: 'my-app',
directives: [SpinnerComponent],
template: `
<spinner-component></spinner-component>
<router-outlet></router-outlet>
`
})
export class MyApp { }
স্পিনার-অংশ (ততক্ষণে সক্রিয়ের মান পরিবর্তন করতে স্পিনার-পরিষেবাতে সাবস্ক্রাইব হবে)
import {Component} from '@angular/core';
import { SpinnerService} from 'path/to/spinner-service';
@Component({
selector: 'spinner-component',
'template': '<div *ngIf="active" class="spinner loading"></div>'
})
export class SpinnerComponent {
public active: boolean;
public constructor(spinner: SpinnerService) {
spinner.status.subscribe((status: boolean) => {
this.active = status;
});
}
}
স্পিনার-পরিষেবা (এই পরিষেবাটির বুটস্ট্র্যাপ)
পরিবর্তনের স্থিতি পরিবর্তন করতে স্পিনার-উপাদান দ্বারা সাবস্ক্রাইব হওয়ার জন্য একটি পর্যবেক্ষণযোগ্য সংজ্ঞা দিন এবং স্পিনারকে সক্রিয় / নিষ্ক্রিয় জানতে এবং সেট করতে ফাংশন করুন।
import {Injectable} from '@angular/core';
import {Subject} from 'rxjs/Subject';
import 'rxjs/add/operator/share';
@Injectable()
export class SpinnerService {
public status: Subject<boolean> = new Subject();
private _active: boolean = false;
public get active(): boolean {
return this._active;
}
public set active(v: boolean) {
this._active = v;
this.status.next(v);
}
public start(): void {
this.active = true;
}
public stop(): void {
this.active = false;
}
}
অন্যান্য সমস্ত রুটের উপাদান
(নমুনা):
import { Component} from '@angular/core';
import { SpinnerService} from 'path/to/spinner-service';
@Component({
template: `<div *ngIf="!spinner.active" id="container">Nothing is Loading Now</div>`
})
export class SampleComponent {
constructor(public spinner: SpinnerService){}
ngOnInit(){
this.spinner.stop(); // or do it on some other event eg: when xmlhttp request completes loading data for the component
}
ngOnDestroy(){
this.spinner.start();
}
}
spinner-service
আপাতত কিছু কোড যুক্ত করেছি এটির কাজটি করার জন্য আপনার কেবল অন্য অংশে প্রয়োজন to এবং মনে রাখবেন এটি এর জন্যangular2-rc-1
কেন কেবল সাধারণ সিএসএস ব্যবহার করছেন না:
<router-outlet></router-outlet>
<div class="loading"></div>
এবং আপনার শৈলীতে:
div.loading{
height: 100px;
background-color: red;
display: none;
}
router-outlet + div.loading{
display: block;
}
বা এমনকি আমরা প্রথম উত্তরের জন্য এটি করতে পারি:
<router-outlet></router-outlet>
<spinner-component></spinner-component>
এবং তারপর সহজভাবে
spinner-component{
display:none;
}
router-outlet + spinner-component{
display: block;
}
এখানে কৌশলটি হ'ল, নতুন রুট এবং উপাদানগুলি সর্বদা রাউটার-আউটলেট পরে প্রদর্শিত হবে , তাই একটি সাধারণ সিএসএস নির্বাচকের সাহায্যে আমরা লোডিংটি প্রদর্শন করতে এবং আড়াল করতে পারি।
প্রথম রুটের জন্য যদি আপনার বিশেষ যুক্তির প্রয়োজন হয় তবে আপনি নিম্নলিখিতটি করতে পারেন:
loaded = false;
constructor(private router: Router....) {
router.events.pipe(filter(e => e instanceof NavigationEnd), take(1))
.subscribe((e) => {
this.loaded = true;
alert('loaded - this fires only once');
});
আমার পৃষ্ঠা ফুটারটি লুকানোর জন্য আমার এটির প্রয়োজন ছিল যা অন্যথায় পৃষ্ঠার শীর্ষে উপস্থিত ছিল appear এছাড়াও যদি আপনি কেবল প্রথম পৃষ্ঠার জন্য কোনও লোডার চান তবে আপনি এটি ব্যবহার করতে পারেন।
আপনি এই বিদ্যমান সমাধানটিও ব্যবহার করতে পারেন । ডেমো এখানে আছে । দেখে মনে হচ্ছে ইউটিউব লোডিং বার। আমি সবেমাত্র এটি পেয়েছি এবং এটি আমার নিজস্ব প্রকল্পে যুক্ত করেছি।