WebDev: Cómo acceder a funciones de miembros en elementos de polímero
Estoy trabajando en un proyecto tonto de Polymer en este momento, que analiza una base de datos de Pokémon y devuelve una imagen de un Pokémon, luego pronuncia el nombre de la criatura por los altavoces. Aquí está el código fuente de mi proyecto.. Es la primera vez que uso Polymer, y ciertamente me estoy enganchando en algunos puntos. Más recientemente, intentaba devolver funciones miembro de un objeto Polymer que creé. Me tomó una eternidad resolver esto, así que quería compartirlo con ustedes en este tutorial.
Nota al margen: también puede buscar mi más detallada artículo sobre componentes web aquí.
La forma incorrecta
Tengo un componente web que se parece a esto:
<x-radial-buttons id="radial-button-template"></x-radial-buttons>
Si trato de acceder a él por su ID….
var temp = document.querySelector("#radial-button-template");
// returns <x-radial-buttons id=”radial-button-template”></x-radial-buttons>
Pero no puedo acceder a ninguna de las funciones. Devuelven «indefinido». Así que si probé esto:
var temp = document.querySelector("#radial-button-template");
temp.getFirstElement // returns undefined
¿Por qué está pasando esto?
La razón detrás de esto se debe a la encapsulación de Shadow DOM. Es a la vez un regalo y una maldición. En este caso, estoy accediendo al elemento, y no a shadowRoot, que expondrá los métodos públicos adjuntos al objeto Shadow DOM. En el siguiente paso, verá cómo puedo acceder a las funciones de miembro en mi elemento personalizado, así como también cómo puedo devolver nodos que se encuentran aún más profundos en mi componente web. Rob Dobson del equipo de polímeros de Google lo explica muy bien en su entrada de blog. Eric Bidleman entra aún más en detalle en su Artículo avanzado de Shadow DOM. Sugiero encarecidamente que se tome el tiempo de leerlos para comprender mejor cómo funciona esta versión del DOM.
Una forma de hacerlo…
var btn = document.querySelector(«x-radial-buttons»); Tenga en cuenta que no estoy usando el símbolo de almohadilla (#) para acceder al elemento, como si fuera una identificación. En su lugar, simplemente debe referirse al nombre del elemento de polímero en sí: document.querySelector(«x-radial-buttons»); así que ahora puedo escribir:
var temp = document.querySelector("x-radial-buttons");
// ALSO returns <x-radial-buttons id="radial-button-template"></x-radial-buttons>
Ahora puedo acceder a todos los miembros:
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>
Por lo tanto, sugiero no asignar una ID a su elemento de polímero en absoluto. Como Rob dejó en claro en los comentarios a continuación, puede consultar un elemento personalizado como lo desee (a través de ID, clase, atributo o nombre del elemento) y obtener lo mismo. Aquí está su ejemplo: http://jsbin.com/qikaya/2/editar
Otra forma de hacerlo…
También puede tomar la ID de un elemento de polímero y acceder a las funciones de los miembros. Esto se hace por ‘listo para polímeros’ evento. Como lo describen los documentos:
Polymer analiza las definiciones de elementos y maneja su actualización asincrónicamente. Si recupera prematuramente el elemento del DOM antes de que tenga la oportunidad de actualizarse, estará trabajando con un HTMLElement simple, en lugar de su elemento personalizado.
Y este es exactamente el problema con el que me estaba topando antes. Estaba tratando de tomar funciones dentro de mi elemento de polímero antes de que el polímero tuviera la oportunidad de potenciar eso. Aquí hay un ejemplo:
<head>
<link rel="import" href="https://www.noupe.com/development/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>
En conclusión, siempre que envuelva las funciones que está tratando de llamar en el preparado para polímeros evento, debería estar listo para comenzar y puede llamar funciones desde su elemento de polímero.
Así es como lo estoy usando
<link href="https://www.noupe.com/development/bower_components/polymer/polymer.html" rel="import">
<link rel="import" href="http://www.noupe.com/paper-radio-group/paper-radio-group.html">
<link rel="import" href="http://www.noupe.com/paper-radio-button/paper-radio-button.html">
<polymer-element name="x-radial-buttons">
<!-- Shadow DOM -->
<template>
<style>
#paper_radio_group {
position: relative;
width: 440px;
height: 50px;
}
</style>
<paper-radio-group selected="English-GB" valueattr="label" selectedindex="1" id="paper_radio_group">
<paper-radio-button label="English-US" id="paper_radio_btn_en-US" on-click="{{ changeAccentUS }}"></paper-radio-button>
<paper-radio-button checked label="English-GB" id="paper_radio_btn_en-GB" on-click="{{ changeAccentGB }}"></paper-radio-button>
<paper-radio-button label="Spanish" id="paper_radio_btn_es-ES" on-click="{{ changeAccentES }}"></paper-radio-button>
</paper-radio-group>
</template> <!-- /Shadow DOM -->
<script>
Polymer('x-radial-buttons', {
/* -- Attributes ------------------------------------------------ */
currentAccent: 'en-US',
//accentArr: ['en-US', 'en-GB, es-ES'],
created: function() {
accentArr = ['en-US', 'en-GB', 'es-ES'];
},
/* -- Methods --------------------------------------------------- */
getCurrentAccent: function() {
return currentAccent;
},
getFirstElement: function () {
console.log(this.$.paper_radio_group.querySelector("#paper_radio_btn_en-US"));
return this.$.paper_radio_group.querySelector("#paper_radio_btn_en-US");
},
getSecondElement: function () {
return this.$.paper_radio_group.querySelector("#paper_radio_btn_en-GB");
},
getThirdElement: function () {
return this.$.paper_radio_group.querySelector("#paper_radio_btn_es-ES");
},
changeAccentUS: function(event, detail, sender) {
console.log("Changed accent to American " + this.currentAccent);
currentAccent = accentArr[0];
//PokémonApp.changeAccent();
},
changeAccentGB: function() {
console.log("Changed accent to British " + this.currentAccent);
//currentAccent = accentArr[1];
PokémonApp.changeAccent();
},
changeAccentES: function () {
console.log("Changed accent to Spanish " + this.currentAccent);
currentAccent = accentArr[2];
PokémonApp.changeAccent();
}
});
</script>
</polymer-element>
(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();
});
}(window.PokémonApp = window.PokémonApp || {}));
<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>
Más aprendizaje en JavaScript
Puede que te sorprenda un poco, pero Microsoft tiene un montón de aprendizaje gratuito sobre muchos temas de código abierto de JavaScript y tenemos la misión de crear mucho más con Borde de Microsoft viniendo. Aquí está la serie de aprendizaje más amplia de nuestro equipo sobre HTML, CSS y JS:
- Consejos prácticos de rendimiento para hacer que su HTML/JavaScript sea más rápido (una serie de 7 partes desde el diseño receptivo hasta los juegos casuales y la optimización del rendimiento)
- La plataforma web moderna JumpStart (los fundamentos de HTML, CSS y JS)
- Desarrollo de aplicaciones universales de Windows con HTML y JavaScript JumpStart (use el JS que ya ha creado para crear una aplicación)
- Y algunas herramientas gratuitas: Comunidad de Visual Studio, Prueba de Azurey herramientas de prueba de navegador cruzado para Mac, Linux o Windows.
Este artículo es parte de la serie de tecnología de desarrollo web de Microsoft. Estamos emocionados de compartir Borde de Microsoft y el nuevo Motor de renderizado EdgeHTML contigo. Obtenga máquinas virtuales gratuitas o realice pruebas de forma remota en su dispositivo Mac, iOS, Android o Windows @ http://dev.modern.ie/
(dpe)
#WebDev #Cómo #acceder #funciones #miembros #elementos #polímero