在新标签页中打开新窗口

33

我想在用户点击按钮时打开一个新窗口,代码如下:

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

但是它报错了:

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

如何纠正以使其正常工作?


window.open('some url'); 可以工作,但如果您想使用angular-universal,最好避免直接操作窗口。 - maxime1992
所以它是否可能呢? - Rhushikesh
我有这个需求,如果你有任何解决方法,请建议。 - Rhushikesh
我不太熟悉angular-universal,但我记得你可以访问变量isBrowser。因此,使用DI将此变量注入到您的应用程序中,以便您可以从任何地方使用它。然后,当您需要使用window.open时,只需像这样包装它:if (isBrowser) { window.open('some url) } - maxime1992
@Rhushikesh,我在使用带有MVC的Angular2应用程序中遇到了弹出窗口打开的问题,请问您能否提供一下示例代码,展示您是如何在应用程序中打开浏览器弹出窗口的。 - Neeraj Kumar Gupta
1个回答

53
< p > window 变量为 undefined 的原因是您在本地作用域中声明了一个名为 window 的变量。

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

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

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

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

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

服务文件

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

    getNativeWindow() {
        return window;
    }
}

组件文件

@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);
    })
}

1
对我没有用,我需要在模块文件中调用它吗? - Hidayt Rahman
@HidaytRahman 是的,你需要在模块文件的提供者中调用它。 - Tharaka

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接