在新标签页中打开新窗口

Rhu*_*esh 32 tabs window typescript angular

我试图在用户点击按钮时打开一个新窗口,如下所示:

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

但是它引发了一个错误:

core.umd.js:3468 TypeError: Cannot read property 'open' of undefined
Run Code Online (Sandbox Code Playgroud)

如何纠正它让它工作?

Kir*_*ndi 51

原因window变量的存在undefined是一个事实,你已经在局部范围内再次声明的变量命名的窗口.

根据范围规则javascript/typescript,在访问全局变量之前,查找局部变量值.此外,当您最初声明一个变量时,它被设置为undefined,因此您收到的错误消息.

因此,您只需更改捕获已打开选项卡引用的变量名称即可

var newWindow = window.open('some_url');
Run Code Online (Sandbox Code Playgroud)

然而,这不是推荐的方法,因为angular2应用程序可以在各种环境中运行,例如移动或呈现服务器端,其中window对象可能可用,也可能不可用.更不用说在测试中模拟窗口对象会非常困难

相反,您可以将window对象包装在服务中并将该服务注入到组件中.这样,您可以使用依赖注入简单地根据环境替换服务实现

服务文件

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

    getNativeWindow() {
        return window;
    }
}
Run Code Online (Sandbox Code Playgroud)

组件文件

@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);
    })
}
Run Code Online (Sandbox Code Playgroud)