简体   繁体   English

Angular2:绑定和回调

[英]Angular2: Binding and Callbacks

I'm trying to create a small Directive to capture the windows global-keyup and then invoke a callback, so I basically captue the global window in a service and the keyup on my Directive: 我试图创建一个小的指令来捕获Windows全局键,然后调用回调,所以我基本上将服务中的全局窗口和指令上的键帽加帽:

export class EnterActivationDirective implements OnInit {
  private _enterClicked: Action;

  @Input() public set enterClicked(action: Action) {
    this._enterClicked = action;
  }

  constructor(public el: ElementRef, public windowWrapperService: WindowWrapperService) {
  }

  ngOnInit() {
    this.windowWrapperService.nativeWindow.onkeyup = this.onWindowKeyUp.bind(this);
  }

  private onWindowKeyUp(event: any) {
    if (event.code === 'Enter' && this._enterClicked) {
      this._enterClicked();
    }
  }
}

The Service and Action-Type aren't that interesting, since the Service just passes the native window and the Action-Type is a generic Callback without any parameters or return-value. Service和Action-Type并不那么有趣,因为Service只是通过本机窗口,而Action-Type是一个通用回调,没有任何参数或返回值。 The logic itself works, but I get some weird effects regarding the binding to the action. 逻辑本身是有效的,但是我对绑定到动作有一些奇怪的效果。 So, one of my other Components registers to the Directive: 因此,我的其他组件之一注册了该指令:

<div appEnterActivation [enterClicked]="onKeyUp.bind(this)">
  <div>
... Amended

Which then triggers a search-operation: 然后触发搜索操作:

 public search(): void {
    this.searchInProgress = true;
    const param = this.createSearchParams();
    this.searchStarted.emit(param);
    this.timeReportEntryApiService.searchTimeReportEntries(param)
      .then(f => {
        const newObjects = ArrayMapper.MapToNewObjects(f, new TimeReportEntry());
        this.searchFinished.emit(newObjects);
        this.searchInProgress = false;
      }).catch(f => {
        this.searchInProgress = false;
        throw f;
      });
  }

  public get canSearch(): boolean {
    return this.form.valid && !this.searchInProgress;
  }

  public onKeyUp(): void {
    debugger ;
    if (this.canSearch) {
      this.search();
    }
  }

Not too much logic here, but if the search is started from the callback, it seems like the properties and functions are in place, but they are on some kind of different object: 这里没有太多逻辑,但是如果搜索是从回调开始的,则似乎属性和函数就位,但是它们位于某种不同的对象上:

  • The searchInProgress-property is set tu true, but on the second enter, it is false again searchInProgress-property设置为true,但是在第二次输入时,再次为false
  • I have some animations and bindings in place, none of them are triggered 我有一些动画和绑定,没有一个被触发

Since everything is working with a plain button, I'm almost certain it kindahow has to do with the callback and the binding to this . 由于所有操作都使用普通按钮,因此几乎可以肯定,它一定与回调和对此的绑定有关。

I researched a bit regarding this bind, but regarding this thread Use of the JavaScript 'bind' method it seems to be needed. 我对此绑定进行了一些研究,但对于此线程,似乎需要使用JavaScript的“ bind”方法 I also tested without binding, but then the this is bound to the global window variable. 我还测试了没有绑定,但是随后将绑定到了全局窗口变量。

Why are you using an @Input ? 为什么要使用@Input Angular made @Output for such a use case: Angular针对这种用例制作了@Output

template: 模板:

<div appEnterActivation (enterClicked)="onEnter()"></div>

class: 类:

export class EnterActivationDirective implements OnInit {

  @Output() 
  public readonly enterClicked: EventEmitter<any> = new EventEmitter();

  @HostBinding('document.keyup.enter')
  onEnter(): void {
      this.enterClicked.emit();
  }

}

No need for difficult checks or wrappers :) 无需进行困难的检查或包装:)

Since you are using TypeScript you can use arrow function, that manages this correctly. 由于您正在使用TypeScript,因此可以使用箭头功能来正确管理this功能。

 public onKeyUp = () => {
    debugger ;
    if (this.canSearch) {
      this.search();
    }
  }

In that case you can just setup the property binding as 在这种情况下,您可以将属性绑定设置为

[enterClicked]="onKeyUp"

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

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