En esta actividad, introduciremos nuevos conceptos de formularios en NativeScript. Lo que realizaremos sobre la aplicación con la que venimos trabajando es en el caso de uso de "Search" y donde nosotros tenemos un listado, ahora hecho con un "ListeView" de elementos, vamos a poner un filtrado, aquí, con una barra de texto y un botón donde pondremos caracteres con los cuales filtraremos estos elementos. Para eso, vamos a hacer un nuevo componente dentro de "search" que se llama "search-form.components.ts", el código es este que ven aquí. Aquí estamos usando un componente, le ponemos el selector "search form" y el "template". En vez de usar un template o URL con una HTML, estamos usando la sintaxis de "Backticks" de estos de JavaScript, 2015 en adelante. Podemos poner "template" de aquí mismo. Cuando es un componente que tiene poco código HTML, vale la pena ahorrarse, quizás, el archivo y usarlo aquí. Aquí, lo que estamos usando es un template que tiene un "TextField" en donde estamos poniendo el "place holder" o "hint", "Ingresar texto" y, luego, estamos vinculando el valor que tiene, que se va a tipear sobre esa caja de texto, lo estamos vinculando a una variable que se llame "textFieldValue" en el componente. Esto, fíjense que tiene corchetes y paréntesis. Algo ya fuimos viendo, vimos que cuando algo tiene corchetes es que le estamos pasando un valor como parámetro a un componente en lo que es un "input", se llama un "input" en ese componente que estamos declarando. Y con el paréntesis son los eventos, cuando se hacen "tap", nos hacen algún tipo de evento sobre nuestro componente. Aquí, que tenemos los dos agregados, es lo que se llama "two-way binding" o "vinculación de datos ida y vuelta". "One way" o "en un sólo sentido" es cuando es o corchetes o paréntesis. Alguien que me dispara un evento cuando usa paréntesis o si usó corchetes le "seteo", le asigno el valor a una propiedad. En este caso, es "two way", "doble dirección". Es decir, que lo que nosotros le pongamos por código TypeScript a esta variable es lo que aparecerá en este "TextField", y si alguien cambia ese valor en ese "TextField", va a aparecer automáticamente reflejado en esta variable TypeScript. Fíjense el componente, lo que estamos haciendo es que estamos dándole entidad de componente al formulario de búsqueda. Esto es porque no queremos poner la caja de texto y el botón en este componente que está acá, que es el "search component.ts ". Solamente, lo que queremos poner en ese es "search component.ts", "html", perdón, es, simplemente, un "tag" de tipo "SearchForm", con este selector, y que ese "tag" ya me renderee, me dibuje todo este componente, y este componente haga toda su lógica, y, cuando lo crea necesario, levante un evento al componente padre. Para eso es que usamos el "search", cuando este componente "search form" detecte que se ha cumplido la condición para disparar una búsqueda y avisarle al componente padre, en esa situación tenemos que emitir un evento. Por eso, el objeto se llama "EventEmitter", "emitidor de eventos", y por eso está anotado como tipo "Output". Tipo "Output" tiene que estar anotado para que donde usemos esto sepan que van a tener que usar paréntesis, "search" entre paréntesis, para indicar el código a ejecutar cuando se dispare este evento. Entonces, nuestro componente es una caja de texto que tiene "two-way binding" con "textFieldValue", que es esta caja de acá, "string", esta caja de texto. Luego, emitimos un evento que se llama "search" y, a su vez, tenemos un botón que cuando nos lo hacen clic viene a ser el botón de "buscar". Este es "Ingresar texto". Ese es el "place holder". Cuando se hace un clic en buscar, "tap" en buscar, llamamos al "onButtonTap". Este es el botón dentro de nuestro componente "search form". Esto viene aquí. Aquí logueamos lo que está escrito para verlo por la consola y hacemos un "if". Sólo hacemos "búsqueda" si ingresaron al menos tres caracteres, o sea, si es mayor a dos la longitud de la cadena de texto, y ahí lo que hacemos es usamos el "event emitter" para emitir un evento. Al emitir un evento, podemos mandarle como argumento del evento o como contexto del evento cualquier objeto que queramos. En este caso, solamente nos interesa... Podríamos mandar a un evento mucho más complejo, lo que nosotros definamos, lo que nos sirva, lo que necesitemos. En este caso, no necesitamos más para el ejemplo que una variable "string". Entonces, vamos a guardar los cambios en este "search form". Luego, este componente, para poder ser usado, los demás componentes que lo quieran usar lo van a tener que conocer de una u otra manera, pero no lo van a poder conocer si este componente no está declarado en ningún módulo. Por eso, tenemos que ir al "search.module". Aquí tendríamos este "feature", "search", ya con dos componentes, el "search.component" que veníamos desde el principio y ahora agregamos el "search-form.component". Para eso, tenemos que agregarlo en "declarations". Obviamente, tenemos que agregar el "import" y hay que seguir las convenciones de que esté ordenado alfabéticamente. Aquí, de esta manera, al agregar en las declaraciones el "SearchFormComponent", este componente va a poder ser utilizado en el HTML, en los "template" de los otros componentes de este módulo, que en este caso es uno solo, es el "search component", como bien sabemos. Antes de dejar el "search module", tenemos que hacer una cosa más. Como vamos a utilizar esta funcionalidad de "two-way binding", en este módulo vamos a tener que crear, para que eso funcione, un módulo más, el "import" de un módulo más que es el "NativeScriptFormsModule", que nos da la funcionalidad necesaria para que funcione de manera correcta, en Angular, el "two-way binding" cuando estamos en NativeScript. De esta manera, tenemos declarado el "search form" y modificado el "module". Ahora, tenemos que usar el "component". Vamos directamente al "template" del "search form" y aquí, arriba de este listado, vamos a agregar una instancia de "search form". Con esta instancia de "search form" se va a dibujar una barrita de búsqueda. Ahora bien, esta barrita de búsqueda o este componente de búsqueda tiene un evento que se llama "search". Entonces, en éste, lo que vamos a tener que hacer es "search", "=", y aquí llamar a una función de TypeScript. Para eso vamos a declararlo, vamos a declarar una función "search" que va a recibir el "string" y lo que vamos a hacer, para que nuestro caso de uso en nuestra pantalla sea reactiva, es decir, que a medida que van haciendo clic se refresquen los resultados, vamos a agregar una variable "string", "array" de "string", que se llame "resultados", que cada vez que nos hacen clic en el botón y llega el código aquí, al "search", lo vamos a llenar con los resultados de la búsqueda. Para eso, vamos a llamar a nuestro servicio, vamos a "buscar". El "buscar" nos va a devolver todo, esto es porque es un ejemplo. Y lo filtramos directamente aquí, a todas las cadenas de este "array" "buscar" que nos es devuelto que contengan el texto que nos están pidiendo buscar, y eso lo asignamos a "resultados". Ahora bien, "resultados" lo tenemos que usar en la "vista" y el "search" tiene que ser llamado cuando se dispare este "search" de acá. A este le vamos a poner otro nombre, mejor vamos a "buscarAhora", así no hay confusiones. Cuando se dispara el evento "search", acá vamos a llamar a "buscar ahora" y tenemos que pasar lo que nos están buscando. Recuerden que nosotros retornamos en el "emit", el objeto de contexto del evento es la propia cadena de texto ingresada, así que, como ya hemos visto en alguna otra actividad, aquí rectamente tenemos que poner "event". Este va a ser la cadena de texto del "string" que nos ingresaron en el "text box". Entonces, aquí el código pasa al "buscar ahora" y el "buscar ahora" filtra los resultados de "noticias service" y lo asigna en resultados. Lo que nos queda es hacer uso de "resultados", en vez de aquí tener esto bindeado al "buscar", vinculado al "array" "buscar" del "noticias service", lo vamos a bindear, a vincular al "this.resultados". Esto hace un "way", un "one-way binding", es decir, una vinculación de un único, hacia un único lado desde este "array" a este objeto. Esto es una funcionalidad también de Angular, gracias a los observables y las características de interfaz reactiva, es decir, que justamente se queda observando los cambios de valores en una variable, en este caso, esto que es un "array" y, cada vez que cambia, lo refleja en la interfaz gráfica. Vamos al "search", vamos a poner la consola, así vemos cuando buscamos algo, ahora ponemos la letra "a", vemos qué buscó la letra "a", pero abajo, nada. Vamos a ponerle ahora adelante "hol". Recuerden que lo que se va agregando en el "array" era un,"hola, hola, hola", todos holas, "hola 2! ", "hola 3!". Así que, "hola" sabemos que todos tienen. Ahí le damos al buscar y nos retornó todo. Si ahora ponemos "hola 2", nos retorna solamente "hola 2". De esta manera, hemos visto el concepto de formularios básicos con "two-way binding". Ustedes, aquí, en este formulario, por ejemplo... Si este formulario fuese para un "editar", algo que podrían hacer es, cuando le instancian, usar una variable, por ejemplo, " [inicial] ="'hola'". Recuerden que acá con corchetes estamos diciendo que estamos pasando algún valor de entrada y lo que viene de este lado es un TypeScript. Por eso ponemos comillas, y aquí lo que haríamos sería definir un "@Input" inicial, dos puntos, esto es de tipo "string". Y aquí tendríamos que poner un "OnInit" y lo tendríamos que implementar, y en el "OnInit" lo que haríamos sería "inicial", "this.textFieldValue", que es el que está vinculado al "text field" igual a "this.inicial". Aquí vamos a darle la razón a que esté en orden alfabético. Obviamente, aquí estamos usando "strings" tanto para el "input" como para los que levanta el evento, pero podrían ser objetos, directamente, objetos tan complejos como ustedes quieran. "Hola", ¿ven? Vino inicializado en "hola" porque lo pasamos como "input". De esta manera, con "strings", reitero, pero estos objetos... Esto queda el comportamiento encapsulado en este componente. Este "input" podría ser un objeto de dominio de ustedes: "alumno", "cliente", lo que sea, y el "EventEmitter" podría ser del mismo tipo. Entonces, recibe el valor inicial de un cliente y emite el valor actualizado, y puede ser tan complejo como ustedes quieran porque esto, al ser un componente, adentro puede tener otros subcomponentes, para hacer un formulario de búsqueda, edición, creación tan complicado, tan complejo, sofisticado como ustedes deseen.