Javascript 如何专注于一个领域?

Javascript 如何专注于一个领域?,javascript,angular,typescript,Javascript,Angular,Typescript,我从Angular 2更新到Angular 4,在文档中使用渲染器2,而不是不推荐使用的渲染器 现在我正在研究渲染器,但找不到一种方法来调用我以前使用的focus()方法 旧方法: this.renderer.invokeElementMethod(元素'focus',[]) 新的aproach是什么 编辑 如果我关注的元素是通过QuerySelector获取的,该怎么办 例如: let inputField = document.querySelectorAll('.dialog input'

我从Angular 2更新到Angular 4,在文档中使用
渲染器2
,而不是不推荐使用的
渲染器

现在我正在研究渲染器,但找不到一种方法来调用我以前使用的
focus()
方法

旧方法:

this.renderer.invokeElementMethod(元素'focus',[])

新的aproach是什么

编辑

如果我关注的元素是通过
QuerySelector
获取的,该怎么办

例如:

let inputField = document.querySelectorAll('.dialog input');
if ( inputField[0] ) {
   inputField[0].focus();
}

由于它是通过
QuerySelector
获得的,因此它上不存在
focus()
方法。

不推荐使用
invokeElementMethod
方法,并且无法返回到新的渲染器中。要将焦点设置为元素,现在只需使用以下命令:

element.nativeElement.focus();
如果您使用的是
document.querySelectorAll
,那么您所做的事情并不是以角度的方式进行的,您应该找到另一种方式。如果没有其他方法,那么同样的原则也适用。
focus()
方法是纯javascript,因此您可以在angular2/typescript中使用它。确保在组件的
ngAfterViewInit
钩子内执行
querySelectorAll
,不过:

ngAfterViewInit() {
   let inputField: HTMLElement = <HTMLElement>document.querySelectorAll('.dialog input')[0];
   inputField && inputField.focus();
}
ngAfterViewInit(){
let inputField:HtmleElement=document.querySelectorAll('.dialog input')[0];
inputField&&inputField.focus();
}
模板引用变量:#inlineEditControl
@ViewChild('inlineEditControl')inlineEditControl:ElementRef;//输入DOM元素
this.inlineEditControl.nativeElement.focus();

您还可以使用渲染器2的方法选择RootElement

例如:

constructor(private renderer: Renderer2) {}

this.renderer.selectRootElement('#domElementId').focus()

,此时html中的domElementIdid='domElementId',如果不直接修改DOM,则此任务似乎无法实现。正如其他人所说,invokeElementMethod()已被弃用。但是,您也会发现使用selectRootElement的问题,因为这不是它的预期目的,最终会丢失DIV中的子元素。下面是一个SO问题的链接,该问题更详细地解释了selectRootElement(因为角度文档非常糟糕):

目前看来,轻松实现目标的唯一方法是使用模板引用变量、视图子级和yourViewChild.nativeElement.focus()(尽管也不建议使用这种做法)

还有一个建议的解决方法,使用此GitHub问题上的FocusService:


在本期中,Tytskyi提到可以实现FocusService,并基于AppModuleBrowser和AppModuleServer提供focus()的不同实现。我不确定这将如何工作,但这可能是目前不使用nativeElement实现这一目标的唯一方法。

如果您声明了
inputField
var的正确类型,您可以使用任何JS查询选择器

对于声明的实例:
let-inputField:HTMLInputElement=document.querySelector('.dialog-input')
允许您呼叫
inputField.focus()
它将工作并且不会抛出TS错误。

如果您正在使用,您可以使用作为辅助功能模块(A11yModule)一部分的方法设置焦点

通过这种方式,您可以避免任何DOM操作,同时避免引用
nativeElement


从'@angular/cdk/a11y'导入{FocusMonitor};
导出类ExampleComponent实现AfterViewInit{
@ViewChild('elem',{static:false})elemRef;
构造函数(专用focusMonitor:focusMonitor){
}
ngAfterViewInit(){
//以编程方式设置焦点。焦点源为“程序”。
this.focusMonitor.focusVia(this.elemRef,'program');
}
}

请查看我的最新问题。我正在使用
document.querySelectorAll
方法。很抱歉,我已经用
document.querySelectorAll
方法更新了我的问题,因为我要关注的字段应该是动态选择的。同样,我们不应该避免直接在nativeElement上调用focus,因为我们当时没有正确使用Angular的抽象层。相反,我们应该使用Render2API吗?@Hassan我已经更新了我的答案,因为我意识到了这一点
querySelectorAll
返回一个
元素数组
,但您可能可以确定它是一个
HtmleElement
,因此您可以键入提示,这样TypeScript就不会抱怨了。是的,它现在与更新的答案配合得很好。非常感谢!:)我们不应该避免直接在nativeElement上调用focus,因为我们没有正确使用Angular的抽象层。相反,我们应该使用Renderer2API吗?@ManuChadha Renderer2上没有这样做的方法:),但也许html self中元素的模板引用和调用focus()更符合这一点。我试图以有角度的方式编写代码,也试图保持抽象完好无损,但不幸的是,框架并不像我想象的那样抽象。在Angular中仍然非常新,所以我可能错了,感谢buddy Renderer2 api selectRootElement为我工作了this.renderer.selectRootElement(this.email.nativeElement.focus();element.nativeElement.focus();//不为Meno工作不是推荐的方法,它说,“selectRootElement()不适用于一般用途,而且,正如您所猜测的,它实际上只在引导中有用。”谢谢。我在寻找这个解释。我知道我们应该使用Render2,但我找不到一个关于如何使用Render2关注输入的示例。奇怪的是,为什么这样的方法在Render2中不可用,因为它看起来非常有用。有什么想法吗?
constructor(private renderer: Renderer2) {}

this.renderer.selectRootElement('#domElementId').focus()