ReferenceError:在TypeScript中未定义HTMLElement

时间:2017-05-21 15:17:22

标签: angular typescript

我是TypeScript的新手,坦率地说,我可能做错了。但是......我试图创建一个" KeyUp Listener"对于将通知"通知"的文本框当用户停止输入时。但是,当我尝试注册该类时,我收到以下错误:

  

异常:调用节点模块失败并显示错误:预渲染失败   因为错误:ReferenceError:未定义HTMLElement

注册

// MODULES
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { UniversalModule } from 'angular2-universal';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';

// COMPONENTS
import { AppComponent } from './components/app/app.component'
import { HeaderComponent } from './components/shared/components/shared-header.component';
import { SampleIndexComponent } from './components/samples/sample.index.component';
import { SampleFormComponent } from './components/samples/sample.form.component';
import { StatusFilterComponent } from './components/samples/filters/status-filter.component';
import { AuthorFilterComponent } from './components/samples/filters/author-filter.component';

// LISTENERS
import { TextboxKeyUpListener } from "./components/shared/services/textbox.keyup.listener";

@NgModule({
    bootstrap: [ AppComponent ],
    declarations: [
        AppComponent,
        HeaderComponent,
        SampleIndexComponent,
        StatusFilterComponent,
        AuthorFilterComponent,
        SampleFormComponent
    ],
    imports: [
        UniversalModule, // <-- Must be first import. This automatically imports BrowserModule, HttpModule, and JsonpModule too.
        FormsModule,
        ReactiveFormsModule,
        RouterModule.forRoot([
            { path: '', redirectTo: 'samples', pathMatch: 'full' },
            { path: 'samples', component: SampleIndexComponent },
            { path: 'form', component: SampleFormComponent },
            { path: '**', redirectTo: 'samples' }
        ])
    ],
    providers: [AuthorFilterNotifier, StatusFilterNotifier, TextboxKeyUpListener]
})
export class AppModule
{
    constructor() { }   
}

NOTIFIER LOOKS LIKE:

// MODULES
import { Injectable, Inject } from '@angular/core';
import { Subject } from 'rxjs/Subject';

@Injectable()
export class TextboxKeyUpListener {

    // CONSTRUCTORS
    constructor(private textbox: HTMLInputElement)
    {
        this.init();
    }

    // PROPERTIES - private
    private typingTimer: NodeJS.Timer;
    private typingTimerInterval: number = 1000;
    private notifyDoneTyping = new Subject<string>();

    // PROPERTIES - public
    public notifyDoneTyping$ = this.notifyDoneTyping.asObservable();

    // METHODS - public
    private keyUp(ev: KeyboardEvent)
    {
        global.clearTimeout(this.typingTimer);
        if(this.textbox.value)
            this.typingTimer = global.setTimeout(this.notify, this.typingTimerInterval);
    }

    // METHODS - private
    private init()
    {
        this.textbox.onkeyup = this.keyUp;
    }

    private notify()
    {
        this.notifyDoneTyping.next(this.textbox.value);
        console.log("Done Typing")
    }
}

1 个答案:

答案 0 :(得分:2)

前段时间我遇到一个问题,就是让Typescript识别出一些基本的DOM类,这些类已经解决了添加

"lib": [
  "es2016",
  "dom"
]

到tsconfig.json文件

我不确定这会对你的情况有所帮助,但可能值得尝试

=============================================== ===========================

评论链触发的其他想法 - 与原始问题无关

使用去抖Rx运算符表示输入结束

如果您需要以简单而优雅的方式表示打字结束,您可能需要考虑使用 Rx debounce运算符。我们的想法是从前端元素(在你的情况下是我想要的输入元素)中创建一个Observable,如果没有从输入接收到新值,则使用debounce发出一个事件在指定的时间内流。您可以查看这些链接以获取更多详细信息(What does RxJS.Observable debounce do?https://blog.thoughtram.io/angular/2016/01/06/taking-advantage-of-observables-in-angular2.html) - 可在线获取更多示例

组件间的沟通

我知道你有两个需要沟通的组件。具体而言,&#34;听众&#34; 需要告诉&#34;其他组件&#34; 打字已完成。

如果&#34;其他组件&#34; 始终包含&#34;听众&#34; ,您可以使用@Output来定义输出&#34;听众&#34; 可以发出的事件以及&#34;其他组件&#34; 可以收听。

如果&#34;其他组件&#34; 未包含&#34;听众&#34; ,则使用服务进行通信即使您还必须考虑服务是单身人士(至少在他们的范围内),也可以考虑。作为Singleton意味着如果您想要收听多个输入字段以进行输入结束,那么您需要弄清楚如何使用多个输入映射Singleton服务。

如果用户界面很复杂,您可以考虑按照redux模式使用中央商店(通过https://github.com/ngrx/storehttps://github.com/angular-redux/store在Angular中提供redux商店模式 - 这是{{3}这解释了基于redux-store的架构的优点和缺点)