为什么文档为空?

时间:2017-07-31 16:58:33

标签: angular selectors-api

**更新**以及接近工作的解决方案:

我正试图让'skip to content'链接跳转到'#content-start'之后的第一个可聚焦元素。

登录-base.component.ts:

import { Component, OnInit } from '@angular/core';
import { Inject, Injectable } from '@angular/core';
import { DOCUMENT } from '@angular/platform-browser';

@Component({
    selector: 'app-login',
    templateUrl: './login.component.html',
    styleUrls: ['./login.component.scss']
})

export class BaseLoginComponent implements OnInit {

    constructor(
        @Inject(DOCUMENT) private document: any
        ) {
    }


    skip() {
        console.log(document);
        console.log(document.querySelector);
        var content = document.querySelector(`#content-start`); // ?? document is null!!
        if (content) {
            var control = content.querySelector('input, button, a');
            console.log(control);
            //if (control) {
            //    control.focus(); // first only
            //}
        }
    };

    ngOnInit() {
        this.document.getElementById('skipLink').onclick = this.skip;
        this.document.getElementById('skipLink').onkeypress = function (e) {
            if (e.keyCode == 13) {
                this.skip();
            }
        }

    }
}

login.component.html:

<div class="login-page">
    <section class="main container" id="content-start">
        <input type="text"/>

这实际上有效,因为 console.log(control)返回

<input _ngcontent-c4="" id="username" name="username">

实际上是正确的控制。

但是我不能只设置.focus(),因为我在那里有一个HTML片段,而不是带有方法的对象,例如.focus();

呃,jQuery的$(控制)有角度等价吗?

3 个答案:

答案 0 :(得分:1)

正如您所知,skipLink应该是您的组件类的方法。为了在this内保持正确的skipLink,您可以使用addEventListener和箭头函数设置事件处理程序:

public ngOnInit() {
    this.document.getElementById('skipLink').addEventListener("click", () => { 
      this.skipLink(); 
    });
    this.document.getElementById('skipLink').addEventListener("keypress", (e) => {
        if (e.keyCode == 13) {
            this.skipLink();
        }
    }
}

private skipLink() {
    let control: HTMLElement = this.document.querySelector('input, button, a');
    if (control) {
        control.focus();
    }
}

您可以在this plunker中看到代码正常工作。

正如Kevin所提到的,使用ViewChild是一种更标准的方式来引用组件中的元素。您可以在目标元素上定义模板引用变量(例如,在下面的组件模板中为#firstButton),使用ViewChild获取对它的引用,并使用nativeElement获取HTML元素本身属性。至于事件处理程序,您可以使用Angular绑定设置它们(例如(click)="skipLink()")。

该方法显示在this plunker

import { Component, NgModule, Inject, ElementRef, ViewChild } from '@angular/core';
...

@Component({
    selector: 'my-app',
    template: `
        <button #firstButton>Focusable Button</button>
        <br/>
        <button (click)="skipLink()">Click here to set focus on first button</button>
    `,
    ...
})
export class App {

    @ViewChild("firstButton") private firstButton: ElementRef;

    private skipLink() {
        this.firstButton.nativeElement.focus();
    }
}   

答案 1 :(得分:0)

这种情况正在发生,因为尚未在ngOnInit中加载DOM。将代码更新为这样,实现AfterViewInit

export class AppComponent implements AfterViewInit{
constructor(
    @Inject(DOCUMENT) private document: any
) { }
}

ngAfterViewInit() {

    this.document.getElementById('skipLink').onclick = skipLink;
    this.document.getElementById('skipLink').onkeypress = function (e) {
        if (e.keyCode == 13) {
            skipLink();
        }
    }

    function skipLink() {
        let content: HTMLElement = this.document.querySelector("#content-start"); // ?? document is null!!
        if (content) {
            let control: HTMLElement = this.document.querySelector('input, button, a');
            console.log(control);
            if (control) {
                // control.focus(); // first only
            }
        }
    }
}

ngAfterViewInit听起来确实如此;它只在最初加载视图时运行。

编辑以回答您的问题:您正在寻找angular.element。关于它的文档非常有用,并且是在Angular中操作元素的更好的编程实践。

答案 2 :(得分:0)

这已经远离最初的实施;如果我更新开场白,那么评论就毫无意义了。

按照凯文的建议按照U sing ViewChild in Angular to Access a Child Component, Directive or DOM Element实施,(除非我误解):

xvar

import { Component, ViewChild, AfterViewInit, ElementRef   } from '@angular/core';

export class AppComponent {

    @ViewChild('firstControl') firstControl: ElementRef;

    skipLink() {
        console.log(this.firstControl);
        //if (this.firstControl) { this.firstControl.focus(); }
    };

不幸的是,这并不是更好。 this.firstControl未定义