2017-09-11 5 views
0

HyperHTMLElement을 사용하는 경우 this.children 또는 this.querySelector()을 사용하여 구성 요소의 내용에 액세스 할 수 있습니다. 이는 요소이기 때문에 가능합니다.hyper.Component를 사용할 때 DOM에 액세스

그러나 hyper.Component을 사용하면 어떻게 비슷한 동작을 얻을 수 있습니까?

내가 염두에두고있는 가상의 예는 React docs입니다. https://facebook.github.io/react/docs/refs-and-the-dom.html - DOM에 특정 노드를 집중시키고 싶습니다.

은 내가이 문제를 해결하기 위해 노력하고 있어요 codepen 샌드 박스가 있습니다 https://codepen.io/asapach/pen/oGvdBd?editors=0010

아이디어는 render()이 같은 Node마다 시간을 반환, 그래서 반환하기 전에 저장할 수 있으며 나중에 액세스를 this.node 같은 것입니다 :

render() { 
    this.node = this.html` 
    <div> 
     <input type="text" /> 
     <input type="button" value="Focus the text input" onclick=${this} /> 
    </div> 
    `; 
    return this.node; 
} 

하지만 내게는 보이지 않습니다. 이 작업을 수행하는 더 좋은 방법이 있습니까?

답변

2

handleEvent 패턴이 도움이됩니다. 이 패턴의 배경은 동작이 이벤트 기반 일 때 DOM 참조를 유지할 필요가 없다는 것입니다. 항상 event.currentTarget을 통해 노드를 검색하고 항상 수신기가 연결된 요소를 가리 키거나 event.target 클릭에 적합한 노드를 가리킬 수 있기 때문입니다. wrap 요소에 연결된 일반 클릭 핸들러 내 다른 곳에서도 데모 케이스 div에 있습니다.

이러한 정보를 사용하려는 경우 루트 요소의 data-is="custom-text-input"처럼 정보를 인식 할 수있는 속성을 사용하여 구성 요소를 풍부하게하고 필요한 다른 작업을 수행 할 수 있습니다. https://codepen.io/WebReflection/pen/LzEmgO?editors=0010

이 다른 포크에서와 같이 구성 요소를 렌더링 한 번 컨텐츠를 해결할 수있는 대안으로 https://codepen.io/WebReflection/pen/RLNyjy?editors=0010

:

onclick(e) { 
    var node = e.target.closest('[data-is=custom-text-input]'); 
    node.querySelector('[type=text]').focus(); 
} 

당신은 당신의 코드 펜의 포크에서 작업 예제를 볼 수 있습니다 하루의 끝에

constructor() { 
    super().node = this.render(); 
    } 

, 사용자 정의 요소 그러나 다만 기본, good'ol의 DOM 노드를 사용하지 않는 경우, 당신은 초기화 할 수 있습니다/당신이 원하는 때마다 그들을 렌더링, 당신은 필요가 없습니다 업그레이드 메커니즘을 기다리는 중입니다.

DOM 요소와 관련된 인스턴스를 주소 지정/변경/변경하기 위해 명시 적으로 노출하지 않는 한 그다지 좋은 방법이 아닙니다.

이러한 가능성이 귀하의 질문에 답변되기를 바랍니다.

+0

'event.target'도 옵션으로 사용하려고 생각하고있었습니다. – DreamSonic

+0

생성자에서'render()'를 호출하는 것이 실제로 좋은 생각이라고 생각하십니까? – DreamSonic

+2

루트 노드를 참조해야하는 경우 조만간 렌더링을 호출해도 아무런 차이가 없습니다. hyperHTML 콘텐츠를 동일한 콘텐츠로 두 번 업데이트하는 데 드는 비용은 거의 0이므로 나중에 구성 요소가 다시 렌더링 되더라도 성능 문제는 발생하지 않습니다. 그러나 실제로 루트 노드에 직접 액세스해야하는 중요하지 않은 구성 요소의 경우 DOM을 사용하여 이벤트 기반 방식으로 작업하는 것을 선호합니다. 확실히 깨끗합니다. –

0

이 구현은 실제로 매우 간단하다 https://github.com/joshgillies/hypercomponent

를 통해 내가 과거에 작업 한 일이다.

class ElementalComponent extends hyper.Component { 
    constructor() { 
    super() 
    const _html = super.html 
    this.html = (...args) => { 
     this.node = _html.apply(this, args) 
     return this.node 
    } 
    } 
} 

class HelloWorld extends ElementalComponent { 
    render() { 
    return this.html`<div>Hello World!</div>` 
    } 
} 

이것은 실제로 잘 작동하며 질문에 대한 인라인입니다. 그러나 hyperHTML은 단일 노드뿐 아니라 여러 노드를 렌더링 할 수 있습니다. 예를 들어 : 위의 ElementalComponent에서

hyper`<div>Hello World!</div>` // returns a single DOM Node 
hyper`<div>Hello</div> <div>World!</div>` // returns multiple DOM Nodes as an Array. 
그래서

this.node 렌더러가 무엇을하고 있는지에 따라 DOM 노드, 또는 배열이 될 수 있습니다.