উত্তর:
এটি বর্তমানে আমার জন্য কাজ করছে (2018-03, এওটি সহ কৌণিক 5.2, কৌণিক-ক্লাইমে পরীক্ষিত এবং একটি কাস্টম ওয়েবপ্যাক বিল্ড):
প্রথমে একটি ইনজেকশনযোগ্য পরিষেবা তৈরি করুন যা উইন্ডোটির একটি রেফারেন্স সরবরাহ করে:
import { Injectable } from '@angular/core';
// This interface is optional, showing how you can add strong typings for custom globals.
// Just use "Window" as the type if you don't have custom global stuff
export interface ICustomWindow extends Window {
__custom_global_stuff: string;
}
function getWindow (): any {
return window;
}
@Injectable()
export class WindowRefService {
get nativeWindow (): ICustomWindow {
return getWindow();
}
}
এখন, সেই পরিষেবাটি আপনার মূল অ্যাপমোডুলের সাথে নিবন্ধ করুন যাতে এটি সর্বত্র ইনজেকশনের ব্যবস্থা করতে পারে:
import { WindowRefService } from './window-ref.service';
@NgModule({
providers: [
WindowRefService
],
...
})
export class AppModule {}
এবং তারপরে আপনাকে যেখানে ইঞ্জেকশন করতে হবে সেখানে window
:
import { Component} from '@angular/core';
import { WindowRefService, ICustomWindow } from './window-ref.service';
@Component({ ... })
export default class MyCoolComponent {
private _window: ICustomWindow;
constructor (
windowRef: WindowRefService
) {
this._window = windowRef.nativeWindow;
}
public doThing (): void {
let foo = this._window.XMLHttpRequest;
let bar = this._window.__custom_global_stuff;
}
...
আপনি nativeDocument
যদি এই অ্যাপ্লিকেশনটিতে এগুলি ব্যবহার করেন তবে আপনি এই পরিষেবাটিতে একইভাবে এবং অন্যান্য গ্লোবালগুলি যুক্ত করতে ইচ্ছুক হতে পারেন ।
সম্পাদনা: ট্রুচাইঞ্জ পরামর্শ সহ আপডেট হয়েছে। সম্পাদনা 2: কৌণিক 2.1.2 সম্পাদনার জন্য আপডেট হয়েছে: যুক্ত করা হয়েছে এওটি নোটগুলি সম্পাদনা 4: any
প্রকারের ওয়ার্ক্রাউন্ড নোট এডিট 5 যুক্ত করা হচ্ছে : একটি উইন্ডোআরফ সার্ভিস ব্যবহারের জন্য আপডেট সমাধান যা একটি ভিন্ন বিল্ড সম্পাদনা 6 সহ পূর্ববর্তী সমাধানটি ব্যবহার করার সময় আমার যে ত্রুটিটি পেয়েছিল তা সংশোধন করে: উদাহরণটি যুক্ত করে কাস্টম উইন্ডো টাইপ করা হচ্ছে
@Inject
আমি No provider for Window
ত্রুটি না পেয়ে । ম্যানুয়ালটির দরকার নেই এটি বেশ সুন্দর @Inject
!
@Inject(Window)
window
তবে এর মধ্যে পরিষেবাটি window
ইউনিট পরীক্ষায় নেটিভ স্টাফগুলিকে আটকানোর অনুমতি দেয় এবং এসএসআর-র হিসাবে আপনি উল্লেখ করেছেন একটি বিকল্প পরিষেবা দেওয়া যেতে পারে যা সার্ভারের জন্য একটি মক / নুপ উইন্ডো প্রকাশ করে। অ্যাঙ্গিটার আপডেট হওয়ার সাথে সাথে আমি এওটিটি যে কারণে উল্লেখ করেছি তা মোড়ক উইন্ডো ভেঙে যাওয়ার প্রাথমিক সমাধানগুলির বেশ কয়েকটি।
কৌণিক মুক্তির সাথে 2.0.0-rc.5 এনজিএমডুল চালু হয়েছিল। পূর্ববর্তী সমাধানটি আমার পক্ষে কাজ করা বন্ধ করে দিয়েছে। এটি ঠিক করার জন্য আমি এটিই করেছি:
app.module.ts:
@NgModule({
providers: [
{ provide: 'Window', useValue: window }
],
declarations: [...],
imports: [...]
})
export class AppModule {}
কিছু উপাদান:
import { Component, Inject } from '@angular/core';
@Component({...})
export class MyComponent {
constructor (@Inject('Window') window: Window) {}
}
'উইন্ডো' স্ট্রিংয়ের পরিবর্তে আপনি ওপেক টোকেনও ব্যবহার করতে পারেন
সম্পাদনা:
অ্যাপমোডুলটি আপনার অ্যাপ্লিকেশনটিকে মূল.স্টে বুটস্ট্র্যাপ করতে ব্যবহৃত হয়:
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
platformBrowserDynamic().bootstrapModule(AppModule)
এনজিমডুল সম্পর্কে আরও তথ্যের জন্য কৌণিক 2 ডকুমেন্টেশন পড়ুন: https://angular.io/docs/ts/latest/guide/ngmodule.html
আপনি সরবরাহকারী সেট করার পরে আপনি কেবল এটি ইনজেকশন করতে পারেন:
import {provide} from 'angular2/core';
bootstrap(..., [provide(Window, {useValue: window})]);
constructor(private window: Window) {
// this.window
}
window.var
পৃষ্ঠার সামগ্রী পরিবর্তন করি তখন পরিবর্তন হয় না
আপনি ইনজেকশন ডকুমেন্ট থেকে উইন্ডো পেতে পারেন।
import { Inject } from '@angular/core';
import { DOCUMENT } from '@angular/common';
export class MyClass {
constructor(@Inject(DOCUMENT) private document: Document) {
this.window = this.document.defaultView;
}
check() {
console.log(this.document);
console.log(this.window);
}
}
এটি কৌনিক ২.১.১ এ কাজ করার জন্য আমাকে @Inject
একটি স্ট্রিং ব্যবহার করে উইন্ডো করতে হয়েছিল
constructor( @Inject('Window') private window: Window) { }
এবং তারপরে এটি উপহাস করুন
beforeEach(() => {
let windowMock: Window = <any>{ };
TestBed.configureTestingModule({
providers: [
ApiUriService,
{ provide: 'Window', useFactory: (() => { return windowMock; }) }
]
});
এবং সাধারণভাবে @NgModule
আমি এটি এটি সরবরাহ করি
{ provide: 'Window', useValue: window }
কৌণিক আরসি 4 এ নিম্নলিখিত কাজগুলি যা উপরের কয়েকটি উত্তরের সংমিশ্রণ, আপনার মূল অ্যাপ্লিকেশনগুলিতে এটি সরবরাহকারীদের যুক্ত করে:
@Component({
templateUrl: 'build/app.html',
providers: [
anotherProvider,
{ provide: Window, useValue: window }
]
})
তারপরে আপনার পরিষেবা ইত্যাদিতে এটি কনস্ট্রাক্টারে ইনজেক্ট করুন
constructor(
@Inject(Window) private _window: Window,
)
@ কম্পোনেন্ট ঘোষণার আগে আপনি এটিও করতে পারেন,
declare var window: any;
সংকলকটি আসলে আপনাকে এখন গ্লোবাল উইন্ডো ভেরিয়েবল অ্যাক্সেস করতে দেবে যেহেতু আপনি এটিকে যে কোনও প্রকারের সাথে ধরে নেওয়া গ্লোবাল ভেরিয়েবল হিসাবে ঘোষণা করেন।
আমি আপনার অ্যাপ্লিকেশনটির যেকোন জায়গায় উইন্ডো অ্যাক্সেস করার পরামর্শ দেব না, যদিও আপনার প্রয়োজনীয় উইন্ডো বৈশিষ্ট্যগুলি অ্যাক্সেস / সংশোধনকারী পরিষেবাগুলি তৈরি করা উচিত (এবং আপনার উপাদানগুলিতে সেই পরিষেবাগুলি ইনজেক্ট করুন) আপনি উইন্ডোটি কী কী করতে পারেন তা পরিবর্তন করার অনুমতি না দিয়ে স্কোপ করার জন্য create পুরো উইন্ডো অবজেক্ট।
আমি উইন্ডো স্ট্রিংয়ের জন্য ওপাক টোকেন ব্যবহার করেছি :
import {unimplemented} from '@angular/core/src/facade/exceptions';
import {OpaqueToken, Provider} from '@angular/core/index';
function _window(): any {
return window;
}
export const WINDOW: OpaqueToken = new OpaqueToken('WindowToken');
export abstract class WindowRef {
get nativeWindow(): any {
return unimplemented();
}
}
export class BrowserWindowRef extends WindowRef {
constructor() {
super();
}
get nativeWindow(): any {
return _window();
}
}
export const WINDOW_PROVIDERS = [
new Provider(WindowRef, { useClass: BrowserWindowRef }),
new Provider(WINDOW, { useFactory: _window, deps: [] }),
];
এবং কেবল আমদানি করার জন্য ব্যবহৃত হয় WINDOW_PROVIDERS
কৌণিক 2.0.0-rc-4 এ বুটস্ট্র্যাপে হয়েছিল।
তবে Angular 2.0.0-rc.5 এর মুক্তির সাথে আমার একটি পৃথক মডিউল তৈরি করতে হবে:
import { NgModule } from '@angular/core';
import { WINDOW_PROVIDERS } from './window';
@NgModule({
providers: [WINDOW_PROVIDERS]
})
export class WindowModule { }
এবং কেবলমাত্র আমার প্রধানের আমদানি সম্পত্তিতে সংজ্ঞায়িত app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { WindowModule } from './other/window.module';
import { AppComponent } from './app.component';
@NgModule({
imports: [ BrowserModule, WindowModule ],
declarations: [ ... ],
providers: [ ... ],
bootstrap: [ AppComponent ]
})
export class AppModule {}
আজকের (এপ্রিল ২০১)) হিসাবে পূর্ববর্তী সমাধানের কোডটি কাজ করে না, আমি মনে করি অ্যাপ্লিকেশনগুলিতে সরাসরি উইন্ডোটি ইনজেক্ট করা সম্ভব এবং তারপরে অ্যাপ্লিকেশনটিতে বিশ্বব্যাপী অ্যাক্সেসের জন্য আপনার প্রয়োজনীয় মানগুলি সংগ্রহ করা সম্ভব, তবে আপনি যদি নিজের নিজস্ব পরিষেবা তৈরি এবং ইনজেকশন করতে পছন্দ করেন তবে একটি উপায় সহজ সমাধান এটি।
https://gist.github.com/WilldelaVega777/9afcbd6cc661f4107c2b74dd6090cebf
//--------------------------------------------------------------------------------------------------
// Imports Section:
//--------------------------------------------------------------------------------------------------
import {Injectable} from 'angular2/core'
import {window} from 'angular2/src/facade/browser';
//--------------------------------------------------------------------------------------------------
// Service Class:
//--------------------------------------------------------------------------------------------------
@Injectable()
export class WindowService
{
//----------------------------------------------------------------------------------------------
// Constructor Method Section:
//----------------------------------------------------------------------------------------------
constructor(){}
//----------------------------------------------------------------------------------------------
// Public Properties Section:
//----------------------------------------------------------------------------------------------
get nativeWindow() : Window
{
return window;
}
}
কৌণিক 4 InjectToken পরিচয় করিয়ে, এবং তারা ডকুমেন্ট নামক একটি টোকেন তৈরি DOCUMENT । আমি মনে করি এটি সরকারী সমাধান এবং এটিটি এটিতে কাজ করে।
এনজিএক্স-উইন্ডো-টোকেন নামে একটি ছোট লাইব্রেরি তৈরি করতে আমি একই যুক্তিটি ব্যবহার করি এবং এটি বার বার করা বন্ধ করে দিতে।
আমি এটিকে অন্য প্রকল্পে ব্যবহার করেছি এবং সমস্যা ছাড়াই এওটিতে তৈরি করেছি।
অন্যান্য প্যাকেজে আমি এটি কীভাবে ব্যবহার করেছি তা এখানে
এখানে নিমজ্জনকারী
আপনার মডিউল মধ্যে
imports: [ BrowserModule, WindowTokenModule ]
আপনার উপাদান
constructor(@Inject(WINDOW) _window) { }
এটা যথেষ্ট
export class AppWindow extends Window {}
এবং কর
{ provide: 'AppWindow', useValue: window }
এওটি খুশি করতে
ডকুমেন্টের মাধ্যমে উইন্ডোটির অবজেক্টে সরাসরি অ্যাক্সেসের সুযোগ রয়েছে
document.defaultView == window
বিল্ট-ইন টোকেন defaultView
থেকে পেয়ে ক্লান্ত হয়ে যাওয়ার পরে DOCUMENT
এটি নালীর জন্য পরীক্ষা করার পরে আমি আরও একটি সমাধান এখানে এলাম :
import {DOCUMENT} from '@angular/common';
import {inject, InjectionToken} from '@angular/core';
export const WINDOW = new InjectionToken<Window>(
'An abstraction over global window object',
{
factory: () => {
const {defaultView} = inject(DOCUMENT);
if (!defaultView) {
throw new Error('Window is not available');
}
return defaultView;
}
});
@Inject(WINDOW) private _window: any
এবং এটি কৌনিক দ্বারা সরবরাহ করা ডকুমেন্ট ইনজেকশন টোকেনের মতো ব্যবহার করবেন?
আমি জানি যে প্রশ্নটি কীভাবে উইন্ডো অবজেক্টটিকে কোনও উপাদানতে ইনজেক্ট করা যায় তবে আপনি কেবল স্থানীয় স্টোরারেজে যাওয়ার জন্য এটি করছেন seems যদি আপনি সত্যিকার অর্থে লোকাল স্টোরেজ চান, তবে কেন এই পরিষেবাটি ব্যবহার করবেন না যা এইচ 5 ওয়েস্টস্টোরেজের মতোই প্রকাশ করে । তারপরে আপনি উপাদানটি এর আসল নির্ভরতাগুলি বর্ণনা করবে যা আপনার কোডটিকে আরও পঠনযোগ্য করে তোলে।
এটি সবচেয়ে সংক্ষিপ্ত / পরিষ্কার উত্তর যা আমি কৌণিক 4 এওটির সাথে কাজ করতে পেয়েছি
সূত্র: https://github.com/angular/angular/issues/12631#issuecomment-274260009
@Injectable()
export class WindowWrapper extends Window {}
export function getWindow() { return window; }
@NgModule({
...
providers: [
{provide: WindowWrapper, useFactory: getWindow}
]
...
})
export class AppModule {
constructor(w: WindowWrapper) {
console.log(w);
}
}
আপনি কৌণিক 4 তে এনজিউন ব্যবহার করতে পারেন:
import { NgZone } from '@angular/core';
constructor(private zone: NgZone) {}
print() {
this.zone.runOutsideAngular(() => window.print());
}
এটি DOCUMENT
বিকল্প হিসাবে চিহ্নিত করা ভাল ধারণা । কৌনিক দস্তাবেজগুলি:
অ্যাপ্লিকেশন এবং রেন্ডারিং প্রসঙ্গগুলি একই নয় (যেমন ওয়েব ওয়ার্কারে অ্যাপ্লিকেশনটি চালানোর সময়) নথি অ্যাপ্লিকেশন প্রসঙ্গে উপলব্ধ থাকতে পারে।
DOCUMENT
ব্রাউজারটির এসভিজি সমর্থন রয়েছে কিনা তা দেখার জন্য এখানে ব্যবহারের উদাহরণ রয়েছে :
import { Optional, Component, Inject } from '@angular/core';
import { DOCUMENT } from '@angular/common'
...
constructor(@Optional() @Inject(DOCUMENT) document: Document) {
this.supportsSvg = !!(
document &&
document.createElementNS &&
document.createElementNS('http://www.w3.org/2000/svg', 'svg').createSVGRect
);
@ ম্যাক্সিসাম এনজিএক্স-উইন্ডো-টোকেনের জন্য ধন্যবাদ । আমি অনুরূপ কিছু করছিলাম তবে আপনার কাছে চলে এসেছি। উইন্ডো পুনরায় আকারের ইভেন্টগুলি শোনার এবং গ্রাহকদের অবহিত করার জন্য এটি আমার পরিষেবা।
import { Inject, Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/fromEvent';
import { WINDOW } from 'ngx-window-token';
export interface WindowSize {
readonly width: number;
readonly height: number;
}
@Injectable()
export class WindowSizeService {
constructor( @Inject(WINDOW) private _window: any ) {
Observable.fromEvent(_window, 'resize')
.auditTime(100)
.map(event => <WindowSize>{width: event['currentTarget'].innerWidth, height: event['currentTarget'].innerHeight})
.subscribe((windowSize) => {
this.windowSizeChanged$.next(windowSize);
});
}
readonly windowSizeChanged$ = new BehaviorSubject<WindowSize>(<WindowSize>{width: this._window.innerWidth, height: this._window.innerHeight});
}
সংক্ষিপ্ত এবং মিষ্টি এবং একটি কবজ মত কাজ করে।
গ্লোবাল ভেরিয়েবলগুলি যখন অ্যাপ্লিকেশন জুড়ে অ্যাক্সেসযোগ্য হয় তখন ডিআই (ডিপেন্ডেন্সি ইনজেকশন) এর মাধ্যমে উইন্ডো অবজেক্ট পাওয়া ভাল ধারণা নয়।
আপনি যদি উইন্ডো অবজেক্টটি ব্যবহার করতে না চান তবে আপনি self
কীওয়ার্ডটিও ব্যবহার করতে পারেন যা উইন্ডো অবজেক্টটিকেও নির্দেশ করে।
ভাবলেন!
export class HeroesComponent implements OnInit {
heroes: Hero[];
window = window;
}
<div>{{window.Object.entries({ foo: 1 }) | json}}</div>
আসলে এখানে উইন্ডো অবজেক্টটি অ্যাক্সেস করা খুব সহজ আমার মূল উপাদান এবং আমি এটির কার্যকারিতাটি পরীক্ষা করেছি
import { Component, OnInit,Inject } from '@angular/core';
import {DOCUMENT} from '@angular/platform-browser';
@Component({
selector: 'app-verticalbanners',
templateUrl: './verticalbanners.component.html',
styleUrls: ['./verticalbanners.component.css']
})
export class VerticalbannersComponent implements OnInit {
constructor(){ }
ngOnInit() {
console.log(window.innerHeight );
}
}
ORIGINAL EXCEPTION: No provider for Window!
। তবে এটি অপসারণ আমার জন্য সমস্যাটি স্থির করে। প্রথম দুটি বৈশ্বিক লাইন ব্যবহার করা আমার পক্ষে যথেষ্ট ছিল।