Limitador de conteo de etiquetas -- javascript campo con jquery camp codereview Relacionados El problema

Tag count limiter


2
vote

problema

Español

Este es un contador de etiquetas que implementé a un sitio. Se supone que el script muestra el número de etiquetas que un usuario aún puede ingresar: el límite se ha establecido en 5 elementos ( 9988777665544330 ). El campo de entrada $(".bootstrap-tagsinput") tiene dos eventos adjuntos a él: un evento Substracts 1 de tagsLeftTmp , el otro agrega 1.

Como puede ver, el principio seco se viole repitiendo esta línea tres veces:

tagsCounter.html(tagsLeftTmp + ' of ' + tagsLimit + ' tags left');

  var tagsLeftTmp = tagsLimit; var tagsCounter = $("#tags-counter"); tagsCounter.html(tagsLeftTmp + ' of ' + tagsLimit + ' tags left');   $(".bootstrap-tagsinput").on('itemAdded', function(e) {           tagsLeftTmp = tagsLeftTmp - 1;    tagsCounter.html(tagsLeftTmp + ' of ' + tagsLimit + ' tags left');     return tagsLeftTmp; });  $(".bootstrap-tagsinput").on('itemRemoved', function(e) {           tagsLeftTmp = tagsLeftTmp + 1;    tagsCounter.html(tagsLeftTmp + ' of ' + tagsLimit + ' tags left');     return tagsLeftTmp; });    

¿Cómo podría hacer que este código se adhiera al principio seco?

Original en ingles

This is a tags counter that I implemented to a site. The script is supposed to display the number of tags that a user can still input - the limit has been set to 5 items (tagsLeftTmp = 5). The input field $(".bootstrap-tagsinput") has two events attached to it - one event substracts 1 from tagsLeftTmp, the other adds 1.

As you can see, the DRY principle is violated by repeating this line three times:

tagsCounter.html(tagsLeftTmp + ' of ' + tagsLimit + ' tags left');

var tagsLeftTmp = tagsLimit; var tagsCounter = $("#tags-counter"); tagsCounter.html(tagsLeftTmp + ' of ' + tagsLimit + ' tags left');   $(".bootstrap-tagsinput").on('itemAdded', function(e) {           tagsLeftTmp = tagsLeftTmp - 1;    tagsCounter.html(tagsLeftTmp + ' of ' + tagsLimit + ' tags left');     return tagsLeftTmp; });  $(".bootstrap-tagsinput").on('itemRemoved', function(e) {           tagsLeftTmp = tagsLeftTmp + 1;    tagsCounter.html(tagsLeftTmp + ' of ' + tagsLimit + ' tags left');     return tagsLeftTmp; });  

How could I make this code adhere to the DRY principle?

     

Lista de respuestas

3
 
vote

probablemente podría encapsular todo eso en una función y llamar a la función tres veces. Podría ser posiblemente una solución ligeramente peor.

Puede crear un evento más genérico siempre que se actualice el recuento de etiquetas. Este evento se activa de package main // try using algoutils so that you can make use of Swap later import ( "fmt" "algoutils" ) func selectionSort(array []int) { // get rid of that ugly type declarator for i := 0; i < len(array) - 1; i++ { min := i for j := i + 1; j < len(array) - 1; j++ { if array[j] < array[min] { min = j } } algoutils.Swap(array, i, min) } } func main() { array := []int{5, 8, 4, 1, 7, 2, 3, 6} fmt.Println("Unsorted array: ", array) selectionSort(array) fmt.Println("Sorted array: ", array) } 0 y package main // try using algoutils so that you can make use of Swap later import ( "fmt" "algoutils" ) func selectionSort(array []int) { // get rid of that ugly type declarator for i := 0; i < len(array) - 1; i++ { min := i for j := i + 1; j < len(array) - 1; j++ { if array[j] < array[min] { min = j } } algoutils.Swap(array, i, min) } } func main() { array := []int{5, 8, 4, 1, 7, 2, 3, 6} fmt.Println("Unsorted array: ", array) selectionSort(array) fmt.Println("Sorted array: ", array) } 1 . Este evento leerá el recuento de etiquetas actual y mostrarlo.

Puede encapsular todo esto en un objeto package main // try using algoutils so that you can make use of Swap later import ( "fmt" "algoutils" ) func selectionSort(array []int) { // get rid of that ugly type declarator for i := 0; i < len(array) - 1; i++ { min := i for j := i + 1; j < len(array) - 1; j++ { if array[j] < array[min] { min = j } } algoutils.Swap(array, i, min) } } func main() { array := []int{5, 8, 4, 1, 7, 2, 3, 6} fmt.Println("Unsorted array: ", array) selectionSort(array) fmt.Println("Sorted array: ", array) } 2 que tiene package main // try using algoutils so that you can make use of Swap later import ( "fmt" "algoutils" ) func selectionSort(array []int) { // get rid of that ugly type declarator for i := 0; i < len(array) - 1; i++ { min := i for j := i + 1; j < len(array) - 1; j++ { if array[j] < array[min] { min = j } } algoutils.Swap(array, i, min) } } func main() { array := []int{5, 8, 4, 1, 7, 2, 3, 6} fmt.Println("Unsorted array: ", array) selectionSort(array) fmt.Println("Sorted array: ", array) } 3 99887766555443314 Methods y puede mostrar automáticamente el contador. Además, podría separar la vista desde el modelo, por lo que 99887766555443315 simplemente mantiene la lógica y 998877766555443316 se creará el HTML asociado en un evento activado por package main // try using algoutils so that you can make use of Swap later import ( "fmt" "algoutils" ) func selectionSort(array []int) { // get rid of that ugly type declarator for i := 0; i < len(array) - 1; i++ { min := i for j := i + 1; j < len(array) - 1; j++ { if array[j] < array[min] { min = j } } algoutils.Swap(array, i, min) } } func main() { array := []int{5, 8, 4, 1, 7, 2, 3, 6} fmt.Println("Unsorted array: ", array) selectionSort(array) fmt.Println("Sorted array: ", array) } 7 Así que todo está desacoplado.


Pero en realidad, ¿vale la pena? ¿Por qué ir tan grandes longitudes? Seco es un buen principio, especialmente cuando tiene una lógica complicada o bases de código grande. Pero para 15 líneas de código desde donde se duplican 3, con una buena razón, ¿por qué usar seco?

La única lógica que encapsularía sería la adición package main // try using algoutils so that you can make use of Swap later import ( "fmt" "algoutils" ) func selectionSort(array []int) { // get rid of that ugly type declarator for i := 0; i < len(array) - 1; i++ { min := i for j := i + 1; j < len(array) - 1; j++ { if array[j] < array[min] { min = j } } algoutils.Swap(array, i, min) } } func main() { array := []int{5, 8, 4, 1, 7, 2, 3, 6} fmt.Println("Unsorted array: ", array) selectionSort(array) fmt.Println("Sorted array: ", array) } 8 para que uno pueda argumentar que tal vez sea mejor poner todo esto en una función. Algo así como package main // try using algoutils so that you can make use of Swap later import ( "fmt" "algoutils" ) func selectionSort(array []int) { // get rid of that ugly type declarator for i := 0; i < len(array) - 1; i++ { min := i for j := i + 1; j < len(array) - 1; j++ { if array[j] < array[min] { min = j } } algoutils.Swap(array, i, min) } } func main() { array := []int{5, 8, 4, 1, 7, 2, 3, 6} fmt.Println("Unsorted array: ", array) selectionSort(array) fmt.Println("Sorted array: ", array) } 9 .

Argumentaría que el código es mejor en este estado. Es lo suficientemente simple, está claro, no la ingeniera demasiado. Tome una nota o deje un comentario si tiene ganas de querer asegurarse de que se refactorará si aumentará en complejidad. , pero tome la decisión de refactorización, entonces, no, ¡así que puede elegir la mejor solución para esa situación! .

Qué, si crea una forma genérica de mostrar ese mensaje y luego decide que desea cambiar el color a rojo cuando le queda una etiqueta. Pero luego algunos usuarios tendrán un límite de etiqueta más grande y también se agregarán etiquetas automáticamente mediante la aplicación que no contará para este límite, excepto cuando la etiqueta agregada automáticamente sea una etiqueta tomada de la preferencia del usuario, en cuyo caso debe contar. Y el color debe ser verde brillante si no hay una etiqueta establecida actualmente, pero no debe colorear en absoluto para móvil porque arruina la interfaz de usuario allí.

obtienes el punto. No resuelva un problema que no tiene .

 

You could probably encapsulate all that in a function and call the function three times. It would arguably be a slightly worse solution.

You could create a more generic event whenever the tag count is updated. This event is triggered from add and remove. This event will read the current tag count and display it.

You could encapsulate all this in an object RemainingTags which has Add methods, Remove methods and can automatically display the counter. Additionally you could sepparate the view from the model so RemainingTags just keeps the logic and RemainingTagsView will create the associated HTML based on an event triggered by RemainingTags so everything is decoupled.


But really, is it worth it? Why go so great lengths? DRY is a nice principle, especially when having a complicated logic or big code bases. But for 15 lines of code from which 3 are duplicated, with a good reason, why use DRY?

The only logic you would encapsulate would be the addition tagsLeftTmp + ' of ' + tagsLimit + ' tags left' so one could argue that maybe it is better to put all this in a function. Something like getTagsLeftMessage(left, max).

I would argue that the code is best in this state. It is simple enough, it is clear, don't over-engineer it. Take a note or left a comment if you feel like wanting to ensure it will be refactored if it will increase in complexity. But take the refactoring decision then, not now, so you can pick the best solution for that situation!.

What if you create a generic way of displaying that message and then you decide you want to change the color to red when you have one tag left. But then some users will have a bigger tag limit and there will also be automatically added tags by the application which will not count toward this limit, except when the automatically added tag is a tag taken from the user preference in which case it must count. And the color should be bright green if there is no tag currently set but should not color at all for mobile because it ruins the UI there.

You get the point. Don't solve a problem you don't have.

 
 
   
   

Relacionados problema

1  Sube y arrastra la imagen dentro de una imagen de máscara  ( Upload and drag the image inside a mask image ) 
Estoy permitiendo a los usuarios subir y arrastrar imágenes con este código. Dame una revisión de esto. Codepen $part = '@CRC := MD5(CONCAT_WS('#', COA...

2  Limpiando una galería de imágenes rotativas  ( Cleaning up a rotating image gallery ) 
He creado una pequeña galería de imágenes para la web. Me propuse querer 3 cosas. 1. Toda la galería tenía una capacidad de respuesta a nivel básica. 2. La ga...

1  Manipulador de eventos repetitivos para un control de interfaz de usuario de la UI  ( Repetitive event handler for a toggling ui control ) 
Siento que este tipo de código podría haber sido escrito más elegante, especialmente con las enormes afirmaciones de IF / ODS. ¿Alguien puede ayudarme a rompe...

3  Página web basada en una muestra de un libro  ( Web page based on a sample from a book ) 
He creado una página web basada en una muestra de un libro. Funciona bien, pero parece haber sido demasiado complicado. dt4 ¿Es posible mejorar la clari...

2  Animaciones de la línea de tiempo  ( Timeline animations ) 
Hice recientemente esta línea de tiempo del campus para mi universidad. Al ver la línea de tiempo en un dispositivo móvil (no una tableta), la barra de nave...

3  Construyendo una tabla HTML utilizando JavaScript  ( Building an html table using javascript ) 
¿Una forma más legible para hacer esto? renderHtmlTable(function(tableItems) { var tableArray,_i,item,_len; tableArray = ['<table id = sampleTable ><...

1  Actualización de una página web de DRUPAL con contenido basado en texto ingresado  ( Updating a drupal web page with content based on inputted text ) 
La intención es actualizar una página web de drupal existente con contenido basado en texto ingresado en un cuadro de texto. La página existente muestra dat...

5  Función de movimiento para un juego  ( Move function for a game ) 
Tengo una función PackageSubpackageSubpackageName6 en este juego que estoy haciendo. Funciona bien, pero me gustaría reducir un poco su tamaño. PackageSu...

8  Escribiendo un widget de jquery: plantilla  ( Writing a jquery widget templating ) 
Estoy haciendo mi primer mayor desarrollo de jQuery. Es un widget para eventos recurrentes, y es como una bestia bastante compleja. El código completo está di...

3  Función de estilo sortable jquery  ( Jquery sortable style function ) 
Esta es una función de clasificación básica escrita en jQuery que mueve los elementos en la DOM alrededor para crear espacios vacíos para un gotpable (). Como...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos