Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
878 views
in Technique[技术] by (71.8m points)

angular - 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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The reason for window variable being undefined is the fact that you have declared a variable named window again in the local scope.

According to the scoping rules of javascript/typescript, before the global variable is accessed, the local variables value is looked up. Also when you initially declare a variable, it is set to undefined, Hence the error message you receive.

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...