代码之家  ›  专栏  ›  技术社区  ›  Alexis Facques

在订阅中,对子组件的文件输入触发click()将不起作用

  •  0
  • Alexis Facques  · 技术社区  · 7 年前

    考虑模板包含文件输入的组件。可以通过调用公共 open() 方法触发对 nativeElement

    @Component({
      selector: 'child',
      template: '<input type="file" #input/>',
    })
    export class ChildComponent {
      @ViewChild('input')
      public input: ElementRef;
    
      public open(): void {
        console.log('OPENING THE FILE INPUT');
        this.input.nativeElement.click();
      }
    }
    

    ChildComponent ParentCompenent ,调用 ChildComponent.open() 在多个上下文中,定义如下:

    @Component({
      selector: 'parent',
      template: '<child></child>',
    })
    export class ParentComponent {
      @ViewChild(ChildComponent)
      public child: ChildComponent;
    
      constructor( private parentService: ParentService ) {
      }
    
      public openChildInput(): void {
        // This works.
        // Output:
        //  OPENING THE FILE INPUT
        //  The file input opens
    
        this.child.open();
      }
    
      public waitAndOpenChildInput(): void {
        parentService.wait()
          .subscribe( () => {
            // This does not work.
            // Output:
            //  "OPENING THE FILE INPUT"
            //  The file input DOES NOT open...
            this.child.open();
          })
      }
    }
    

    在这两种情况下 打开() console.log 不显示);然而,当从订阅调用时,文件输入似乎不愿意自己打开。

    提前谢谢。。。

    1 回复  |  直到 7 年前
        1
  •  3
  •   ggradnig    7 年前

    出于安全原因,在现代浏览器中不可能通过编程方式调用 click 除非 它发生在 用户交互

    async 上下文和浏览器将不会打开文件对话框。

    你只能通过使你的可观测同步来解决这个问题(实际上,几乎所有预设的可观测都是同步的)。如果你有一个HTTP请求,这是不可能的,你必须这样做 look for alternatives for opening the file dialog (尽管我不确定这些是否适用于您的设置)。

    Here is an GitHub issue