简体   繁体   English

在新标签页中打开新窗口

[英]Open new window in new tab

I am trying to open a new window when user click on button as follows: 我试图在用户点击按钮时打开一个新窗口,如下所示:

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

but it's throwing an error: 但是它引发了一个错误:

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

How to correct it to get it working? 如何纠正它让它工作?

The reason for window variable being undefined is the fact that you have declared a variable named window again in the local scope . window变量undefined的原因是您已在本地范围内再次声明了名为window的变量

According to the scoping rules of javascript/typescript , before the global variable is accessed, the local variables value is looked up. 根据javascript/typescript的范围规则,在访问全局变量之前,查找局部变量值。 Also when you initially declare a variable, it is set to undefined, Hence the error message you receive. 此外,当您最初声明一个变量时,它被设置为undefined,因此您收到的错误消息。

So all you have to do is simply change the variable name in which you capture the opened tab's reference 因此,您只需更改捕获已打开选项卡引用的变量名称即可

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

However this is not the recommended approach as angular2 apps can run in a variety of environments such as mobile or be rendered server side where window object may or may not be available. 然而,这不是推荐的方法,因为angular2应用程序可以在各种环境中运行,例如移动或渲染服务器端,其中window对象可能可用或不可用。 Not to mention it would be very hard to mock the window object in tests 更不用说在测试中模拟窗口对象会非常困难

Instead you can wrap the window object in a service and inject that service into your component. 相反,您可以将window对象包装在服务中,并将该服务注入到组件中。 This way you can simply substitute the service implementation according to the environment, using Dependency injection 这样,您可以使用依赖注入简单地根据环境替换服务实现

The service file 服务文件

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

    getNativeWindow() {
        return window;
    }
}

The component file 组件文件

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM