angular - Öppna nytt fönster i ny flik


Jag försöker öppna ett nytt fönster när användaren klickar på knappen enligt följande:

protected assignActity(type: string): void {
    var window = window.open('/#/link');
    this.Service.assignActivity(type).subscribe(res => {
      window.location = '/#/link/' + res;
      console.log(res);
    })
  }

men det ger ett fel:

core.umd.js:3468 TypeError: Cannot read property 'open' of undefined

Hur rättar man till det för att få det att fungera?

Svar #1

Anledningen till att window-variabeln är undefined är det faktum att du har deklarerat en variabel med namnet window igen i det lokala området.

Enligt scopingsreglerna i javascript/typescript, innan den globala variabeln nås, letas värdet av den lokala variabeln upp. Även när du initialt deklarerar en variabel, sätts den till undefined, därav felmeddelandet du får.

Så allt du behöver göra är helt enkelt att ändra variabelnamnet där du fångar den öppnade flikens referens

var newWindow = window.open('some_url');

Detta är dock inte den rekommenderade metoden eftersom Angular2-appar kan köras i en mängd olika miljöer, såsom mobila enheter eller renderas på serversidan där window-objektet kanske finns eller inte. För att inte tala om att det skulle vara mycket svårt att imitera window-objektet i tester.

Istället kan du kapsla in window-objektet i en tjänst och injicera den tjänsten i din komponent. På detta sätt kan du helt enkelt byta ut tjänstens implementation beroende på miljön, genom att använda beroendeinjektion

Tjänstefilen

@Injectable()
export class WindowRef {
    constructor() {}

    getNativeWindow() {
        return window;
    }
}

Komponentfilen

@Component({
  selector : 'demo',
  template : '<div> Demo </div>'
})
class DemoComponent {

   nativeWindow: any
   constructor( private winRef: WindowRef ) { 
       this.nativeWindow = winRef.getNativeWindow();
   }

    protected assignActity(type: string): void {
       var newWindow = this.nativeWindow.open('/#/link');
       this.Service.assignActivity(type).subscribe(res => {

       newWindow.location = '/#/link/' + res;
       console.log(res);
    })
}

Relaterade artiklar