简体   繁体   English

角2/4分量操纵动态元素的dom?

[英]angular 2/4 component manipulate the dom at dynamic elements?

I have a nav component for my header, with a template like: 我的标头包含nav组件,其模板如下:

<nav><!--hamburger menu and stuff--></nav>
<aside><!--dropdown--></aside>

I also have other components with expanding menus. 我还有其他具有扩展菜单的组件。 I am writing this site using aria-expanded and hidden attributes for accessibility reasons. 由于可访问性原因,我使用aria-expandedhidden属性编写此网站。

It is natural to use the aria attributes to toggle the expansion of the drawers, like with this javascript: 很自然地可以使用aria属性来切换抽屉的展开,例如以下javascript:

let toggleMap = { true: 'false', false: 'true' }
//...
  toggleExpansion (sel) {  
    let state = document.querySelector(sel).getAttribute('aria-expanded')

    if(!Object.keys(toggleMap).includes(state)) // safety check
      return

    document.querySelector(sel)
      .setAttribute('aria-expanded', toggleMap[state])

    JSON.parse(state)? // it's safe now, because of the safety check
      document.querySelector(sel)
        .setAttributeNode(document.createAttribute('hidden')):
      document.querySelector(sel).removeAttribute('hidden')
  }

I can include something like that in my components easily enough, following the steps: 我可以按照以下步骤很容易地在我的组件中包含类似的内容:

  1. in tsconfig.json , set "allowJS": true tsconfig.json中 ,将"allowJS": true设置为"allowJS": true
  2. in a component, import the function, then use that function as a method in the component. 在组件中,导入函数,然后将该函数用作组件中的方法。

However, that directly accesses the dom. 但是,这直接访问了dom。 How can I continue to use a method like toggleExpansion (in that it accesses the dom dynamically, receiving an argument for which element to manipulate, thereby being reusable in various components), but write this in a more angular way, using template variables or such -- preferably somehow as a mixin or something. 我如何继续使用像toggleExpansion这样的方法(因为它可以动态访问dom, 接收要操作的元素的自变量 ,从而可以在各种组件中重用),但是可以使用模板变量等以更角度的方式编写它-最好以某种混音或其他方式使用。

I asked on the gitter channel for angular, already onto the idea: 我在gitter频道上询问角度,已经想到了:

how do you refer to template variables from within the template? 您如何从模板中引用模板变量? like <li (click)="genericModifier(templateVariable)"> <li (click)="genericModifier(templateVariable)">

Miloš Lapiš responded that my syntax was correct. MilošLapiš回答说我的语法正确。 From there I was able to work out a solution. 从那里,我得以制定出解决方案。

  1. in each component, you will have to specify the drawer that is going to expand, both in the template and component. 在每个组件中,您都必须在模板和组件中指定要扩展的抽屉。

template 模板

<nav><!--hamburger menu and stuff--></nav>
<aside #drawer><!--dropdown--></aside>

component 零件

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

// in the component:
export class NavigationComponent implements OnInit {
  @ViewChild('drawer') drawer: ElementRef;
  1. now in the component, you will call toggleExpansion rather like before, but this time passing the this context: 现在,在组件中,您将像以前一样调用toggleExpansion ,但是这次传递了以下上下文:

component 零件

import { library } from 'CommonUtils'
//..
  toggleExpansion(template_variable) { library.toggleExpansion(this, template_variable) }
  1. We can then convert the function to work with elementRef 's like so: 然后,我们可以将函数转换为与elementRef一起使用, elementRef所示:

CommonUtils 通用工具

  toggleExpansion (context, tva) {
    let ele = context[tva].nativeElement  
    let state = ele.getAttribute('aria-expanded')

    if(!Object.keys(toggleMap).includes(state)) // safety check
      return

    state = JSON.parse(state)      

    ele.setAttribute('aria-expanded', toggleMap[state])

    state?
      ele.setAttributeNode(document.createAttribute('hidden')):
      ele.removeAttribute('hidden')
  }

在此链接中回答,您可以看到: https : //github.com/aimprogman/DomNodeAngular4

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

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