Toegang krijgen tot lidfuncties in polymeerelementen

Dit artikel maakt deel uit van een webdev-tech-serie van Microsoft. Bedankt voor het steunen van de partners die SitePoint mogelijk maken.

Ik werk op dit moment aan een dwaas Polymer-project, dat een Pokémon-database ontleedt en een afbeelding van een Pokémon retourneert, en vervolgens de naam van het wezen uit je speakers spreekt. Hier is de broncode voor mijn project.

Het is de eerste keer dat ik Polymer gebruik en ik raak zeker op een paar plekken vast. Meest recent probeerde het lidfuncties terug te geven van een Polymer-object dat ik heb gemaakt. Het kostte me een eeuwigheid om hier achter te komen, dus ik wilde het in deze tutorial met je delen.

Sidenote:je kunt hier ook zoeken naar mijn meer gedetailleerde beschrijving van Web Components.

De verkeerde manier

Ik heb een webcomponent die er als volgt uitziet:

<x -radial-buttons id="radial-button-template"></x>

Als ik probeer toegang te krijgen via zijn ID...

var  temp = document.querySelector("#radial-button-template");
// returns <x -radial-buttons id="radial-button-template"></x>

Ik heb geen toegang tot een van de functies erin. Ze retourneren undefined . Dus als ik dit probeerde:

var  temp = document.querySelector("#radial-button-template");
temp.getFirstElement  // returns undefined

Waarom gebeurt dit?

Dit komt door de inkapseling van de Shadow DOM. Het is zowel een gave als een vloek. In dit geval heb ik toegang tot het element en niet tot de shadowRoot , die de openbare methoden blootlegt die aan het Shadow DOM-object zijn gekoppeld.

In de volgende stap zul je zien hoe ik toegang kan krijgen tot de lidfuncties in mijn aangepaste element, en hoe ik knooppunten kan retourneren die nog dieper in mijn webcomponent liggen.

Rob Dobson van het Polymer-team van Google legt dit goed uit in deze blogpost. Eric Bidleman gaat nog meer in detail in zijn geavanceerde Shadow DOM-artikel. Ik raad ten zeerste aan de tijd te nemen om deze door te lezen om beter te begrijpen hoe deze versie van de DOM werkt.

Eén manier om het te doen

var btn = document.querySelector("x-radial-buttons");

Merk op dat ik het hash-symbool (#) niet gebruik om toegang te krijgen tot het element, alsof het een ID is. In plaats daarvan moet je gewoon verwijzen naar de naam van het polymeer-element zelf:

document.querySelector("x-radial-buttons");

dus nu kan ik schrijven:

var temp = document.querySelector("x-radial-buttons");
// ALSO returns <x-radial-buttons id="radial-button-template"></x-radial-buttons>

Nu heb ik als volgt toegang tot alle leden:

var temp = document.querySelector("x-radial-buttons");
temp.getFirstElement
// returns <paper-radio-button label="English-US" id="paper_radio_btn_en-US" on-click="{{ changeAccentUS }}" role="radio" tabindex="0" aria-checked="false" aria-label="English-US"></paper-radio-button>

Daarom raad ik aan om geen ID toe te wijzen aan uw polymer-element helemaal niet. Zoals Rob duidelijk heeft gemaakt in de opmerkingen hieronder, kun je een aangepast element opvragen zoals je wilt (via ID , class , attr , of elementnaam) en krijg hetzelfde. Hier is zijn voorbeeld: http://jsbin.com/qikaya/2/edit

Een andere manier om het te doen...

Je kunt ook de ID van een polymeerelement pakken en toegang krijgen tot de ledenfuncties.

Dit gebeurt door middel van een ‘polymeer-ready’ event. Zoals de documenten het beschrijven:

Polymeer ontleedt elementdefinities en verwerkt hun upgrade asynchroon . Als je het element voortijdig uit de DOM ophaalt voordat het de kans krijgt om te upgraden, werk je met een gewoon HTML-element in plaats van je aangepaste element.

En dit is precies het probleem waar ik eerder tegenaan liep. Ik probeerde functies te pakken binnen mijn polymer-element voordat Polymer de kans kreeg om te upgraden het. Hier is een voorbeeld:

<head>
  <link rel="import" href="path/to/x-foo.html">
</head>
<body>
  <x-foo></x-foo>
  <script>
    window.addEventListener('polymer-ready', function(e) {
      var xFoo = document.querySelector('x-foo');
      xFoo.barProperty = 'baz';
    });
  </script>
</body>

Tot slot, zolang u de functies die u probeert aan te roepen in de polymeer-ready . zet evenement, zou je goed moeten zijn om te gaan en functies van je polymeer-element kunnen aanroepen.

Hoe ik het gebruik

(function (PokémonApp) {

// Grab inputs and button for speech-to-text
var form                 = document.querySelector('#player-form'),
    input                = document.querySelector('#player-input'),
    playerElement        = document.querySelector('#player-element'),
    xPokémon             = document.querySelector('#x-Pokémon'),
    btnChangeAccent      = document.querySelector('#btn-change-accent'),
    radialButtonTemplate = document.querySelector("#radial-button-template"),
  	playerAccent     = playerElement.getAttribute("accent");

// Take text from input & set it as the text that the speaker will say.
// Set the name of the Pokémon, which angular will then grab from the Pokémon DB 
input.addEventListener('input', function (e) {
	playerElement.setAttribute('text', input.value);
	xPokémon.name = input.value;
});


// Say the text when button is pressed
form.addEventListener('submit', function (e) {
	e.preventDefault();
	playerElement.speak();
	var btn = document.querySelector("x-radial-buttons");
	btn.getFirstElement();
});
<header>
<h1>article header h1</h1>
<p>This web app takes advantage of Web Components and Polymer to enable new HTML features in the browser.</p>
<p>
	In this particular case, we are using <a href="https://github.com/passy/x-Pokémon">
	the x-Pokémon web component </a> to pull the images from a database, as well as the 
	<a href="http://zenorocha.github.io/voice-elements/">voice-elements web component</a> to speak the name of the Pokémon we entered.							
</p>
<h2>Change the accent</h2>
<x-radial-buttons id="radial-button-template"></x-radial-buttons>
</header>

Meer JavaScript leren

Het zal je misschien een beetje verbazen, maar Microsoft heeft een heleboel gratis informatie over veel open source JavaScript-onderwerpen en we zijn op een missie om nog veel meer te creëren met Microsoft Edge eraan.

Dit is de bredere leerreeks van ons team over HTML, CSS en JS:

  • Praktische prestatietips om uw HTML/JavaScript sneller te maken (een 7-delige serie van responsief ontwerp tot casual games tot prestatie-optimalisatie)
  • Het moderne webplatform JumpStart (de grondbeginselen van HTML, CSS en JS)
  • Een universele Windows-app ontwikkelen met HTML en JavaScript JumpStart (gebruik de JS die je al hebt gemaakt om een ​​app te bouwen)
  • En enkele gratis tools:Visual Studio Community, Azure Trial en cross-browser testtools voor Mac, Linux of Windows.

Dit artikel maakt deel uit van een webdev-tech-serie van Microsoft. We zijn verheugd om Microsoft Edge en de nieuwe EdgeHTML-renderingengine met u te delen. Download gratis virtuele machines of test op afstand op uw Mac-, iOS-, Android- of Windows-apparaat op http://dev.modern.ie/