2012-06-26 19 views
5

Uso la aplicación móvil Handlebar in my Rails 3.2 jquery.Rango dentro de la declaración de la caja del interruptor en Coffeescript

Estoy intentando escribir una declaración de caso interruptor dentro de un método CoffeeScript como

Handlebars.registerHelper 'status', (blog) -> 
    switch(parseInt(blog.status)) 
    when [0..20] 
     status = "active" 
    when [20..40] 
     status = "Moderately Active" 
    when [40..60] 
     status = "Very Active" 
    when [60..100] 
     status = "Hyper Active" 
    return status 

no estoy recibiendo ningún resultado. Cómo usar el rango en cuándo. Sugerir

+2

¿Por qué funcionaría? Este [problema de github] (https://github.com/jashkenas/coffee-script/issues/1383) parece decir que esta sintaxis no fue aceptada. –

Respuesta

16

Su switch no funcionará como Cygal notas en los comentarios (es decir, consulte issue 1383). Un switch es sólo un glorificado if(a == b) construcción y tiene que ser capaz de decir cosas como:

a = [1,2,3] 
switch a 
... 

para que funcionen cuando switch en una matriz. Los diseñadores de CoffeeScript pensaron que agregar un caso especial (frágil) para manejar matrices (que es todo [a..b]) especialmente no valía la pena.

Puede hacerlo con un if:

Handlebars.registerHelper 'status', (blog) -> 
    status = parseInt(blog.status, 10) 
    if 0 <= status <= 20 
    'Active' 
    else if 20 < status <= 40 
    'Moderately Active' 
    else if 40 < status <= 60 
    'Very Active' 
    else if 60 < status <= 100 
    'Hyper Active' 
    else 
    # You need to figure out what to say here 

O con un cortocircuito return s como esto:

Handlebars.registerHelper 'status', (blog) -> 
    status = parseInt(blog.status, 10) 
    return 'Something...'  if status <= 0 
    return 'Active'   if status <= 20 
    return 'Moderately Active' if status <= 40 
    return 'Very Active'  if status <= 60 
    return 'Hyper Active'  if status <= 100 
    return 'Something else' # This return isn't necessary but I like the symmetry 

en cuenta que tiene tres casos especiales que usted necesita para agregar cadenas para:

  1. status < 0.
  2. status > 100.
  3. status es NaN. Este caso generalmente caería bajo la rama final "no es menor o igual a 100" ya que NaN => n y NaN <= n son ambos falsos para todos n.

Sí, está absolutamente seguro de que el estado siempre estará dentro del rango supuesto. Por otro lado, lo imposible sucede todo el software de tiempo (de ahí la lista de correo comp.risks) y no hay una buena razón para dejar agujeros que se llenan tan fácilmente.

También tenga en cuenta la adición del argumento radix a la llamada parseInt, no le gustaría un cero inicial para hacer un lío de cosas. Sí, el argumento de raíz es opcional, pero realmente no debería ser así y sus dedos deberían agregar automáticamente el , 10 a cada llamada de parseInt que realice.

+1

Una respuesta tan buena: D. Me gusta la brevedad de la segunda solución, pero también me gusta la "todo-es-una-expresividad" de la primera. ¿Puedo proponer unir ambos [utilizando una expresión 'swtich '] (http://goo.gl/QKKAq)? = D (no quiero robar ningún punto publicando eso como una nueva respuesta) – epidemian

+0

@epidemian: Eso parece una buena alternativa para mí, tengo muchos puntos y no me importa compartir, así que deberías dejarlo como una respuesta. Probablemente usaría el segundo, me gusta el efecto de "es una tabla de búsqueda en línea". –

+0

OK, agregué una respuesta como apéndice suyo. – epidemian

8

Añadiendo un poquito a mu is too short's answer, puede transformar su segundo fragmento de código en una expresión switch:

Handlebars.registerHelper 'status', (blog) -> 
    status = parseInt(blog.status, 10) 
    switch 
    when status <= 0 then 'Something...'  
    when status <= 20 then 'Active' 
    when status <= 40 then 'Moderately Active' 
    when status <= 60 then 'Very Active' 
    when status <= 100 then 'Hyper Active' 
    else 'Something else' 

Esto es básicamente lo mismo que hacer un switch (true) en JavaScript (aunque el compilador CS generará una switch (false) statement with the negated conditions a asegurar resultados booleanos de las expresiones ... creo).


Y la razón por la switch sobre rangos que no funciona es que los rangos de literales en CS representan lisos viejos matrices JS (aunque el compilador hacer algunos trucos de optimización cuando se hace algo así como for i in [1..something]), por lo que cuando están encontrado dentro de un switch que son tratados like normal array values:

// Generated JS for question's CS code: 
switch (parseInt(blog.status)) { 
    case [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]: 
    status = "active"; 
    break; 
    case [20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40]: 
    status = "Moderately Active"; 
    break; 
    case [40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60]: 
    status = "Very Active"; 
    break; 
    case (function() { 
     _results = []; 
     for (_i = 60; _i <= 100; _i++){ _results.push(_i); } 
     return _results; 
    }).apply(this): 
    status = "Hyper Active"; 
} 

el valor dentro de la instrucción switch es, básicamente, en comparación con el uso de cada valor case===, que sólo funciona para las primitivas, no para las matrices (e incluso si funcionó para matrices, estaría probando la igualdad de matrices, no si el valor ed switch está contenido en las matrices ed case).

+1

Mira, valió la pena hacerlo. No hubiera pensado en esa forma de 'cambiar', pero la próxima vez lo haré. Creo que tienes razón, pero el contexto booleano y el uso de 'switch (false)' en lugar de 'switch (true)'. –

Cuestiones relacionadas