ค้นหาเว็บไซต์

typescript - วิธีการฉีด Document ใน service?


ฉันมีแอปพลิเคชัน Angular 2 สำหรับการสร้าง mock ของวัตถุ Document ในการทดสอบ ฉันต้องการฉีดมันเข้าไปใน service แบบ:

import { Document } from '??' 

@Injectable()
export class MyService {
  constructor(document: Document) {}
}

บริการ Title ของ Angular ใช้วิธี getDOM() ภายใน

มีวิธีง่าย ๆ ในการฉีด Document เข้าไปในบริการหรือไม่? นอกจากนี้ ฉันควรอ้างอิงมันในอาร์เรย์ providers อย่างไรดี?

คำตอบ #1

สิ่งนี้ได้รับการสนับสนุนโดย Angular มาสักระยะแล้ว

คุณสามารถใช้ค่าคงที่ DOCUMENT ที่มาจากแพ็กเกจ @angular/common ได้

คำอธิบายของค่าคงที่ DOCUMENT (นำมาจากเอกสาร API):

โทเค็น DI ที่แทนบริบทการเรนเดอร์หลัก ในเว็บเบราว์เซอร์ นี่คือเอกสาร DOM

ตัวอย่างดังแสดงด้านล่าง:

my-service.service.ts:

import { Inject, Injectable } from '@angular/core';
import { DOCUMENT } from '@angular/common';

@Injectable()
export class MyService {
  constructor(@Inject(DOCUMENT) private document: Document) {}
}

my-service.service.spec.ts

import { provide } from '@angular/core';
import { DOCUMENT } from '@angular/common';

import { MyService } from './my-service';

class MockDocument {}

describe('MyService', () => {
  beforeEachProviders(() => ([
    provide(DOCUMENT, { useClass: MockDocument }),
    MyService
  ]));

  ...
});

คำตอบ #2

ฉันไม่สามารถแสดงความคิดเห็นโดยตรงต่อคำถามของ adamdport ได้ (ยังไม่ได้แต้มเครดิต 50 คะแนน) แต่ต่อไปนี้คือสิ่งที่ระบุไว้ในเอกสารของ Angular

อ้างอิงบล็อก @GünterZöchbauer ดูเหมือนว่า DOCUMENT เลิกใช้แล้ว มีความคิดเห็นบ้างไหมว่าจะทำอย่างไรเมื่อมันหายไป? ตัวอย่างเช่น เราจะตั้งค่า favicon แบบไดนามิกได้อย่างไร

แทนที่จะนำเข้าจาก platform browser แบบนี้:

import { DOCUMENT } from '@angular/platform-browser';

นำเข้าจาก angular common:

import {DOCUMENT} from '@angular/common';

คำตอบ #3

นอกเหนือจากคำตอบของ @ Günter Zöchbauer

Angular กำหนด DOCUMENT เป็น InjectionToken

export const DOCUMENT = new InjectionToken<Document>('DocumentToken');

dom_tokens.ts

และฉีดมันด้วยเอกสารใน browser.ts

{provide: DOCUMENT, useFactory: _document, deps: []}


export function _document(): any {
  return document;
}

ดังนั้น เมื่อเราใช้มัน เราเพียงแค่ต้องฉีด @Inject(DOCUMENT)

หรือใช้โทเค็นโดยตรงใน deps:[DOCUMENT]

บทความที่เกี่ยวข้อง