2012-06-26 25 views
5

Tôi đang sử dụng Thanh công cụ trong ứng dụng di động của tôi Rails 3.2 jquery.Phạm vi bên trong bảng sao kê báo cáo chuyển đổi trong Coffeescript

Tôi cố gắng để viết một tuyên bố trường hợp chuyển đổi bên trong một phương pháp Coffeescript như

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 

tôi không nhận được bất kỳ kết quả. Cách sử dụng phạm vi khi nào. Vui lòng đề xuất

+2

Tại sao tính năng này hoạt động? Vấn đề [github] (https://github.com/jashkenas/coffee-script/issues/1383) dường như nói rằng cú pháp này không được chấp nhận. –

Trả lời

16

switch của bạn sẽ không hoạt động như ghi chú Cygal trong các nhận xét (ví dụ: xem issue 1383). Một switch chỉ là một tôn vinh if(a == b) xây dựng và bạn cần để có thể nói những câu như:

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

và đã cho nó hoạt động khi bạn switch trên một mảng. Các nhà thiết kế CoffeeScript nghĩ rằng thêm một trường hợp đặc biệt (mong manh) để xử lý các mảng (tất cả là [a..b]) đặc biệt không đáng giá.

Bạn có thể làm điều đó với một 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 

Hoặc với ngắn mạch return s như thế này:

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 

Lưu ý rằng bạn có ba trường hợp đặc biệt mà bạn cần phải thêm các chuỗi cho:

  1. status < 0.
  2. status > 100.
  3. statusNaN. Trường hợp này thường sẽ nằm trong nhánh cuối cùng "nó không nhỏ hơn hoặc bằng 100" kể từ NaN => nNaN <= n đều là sai cho tất cả n.

Có, bạn hoàn toàn chắc chắn rằng trạng thái sẽ luôn nằm trong phạm vi được giả định. Mặt khác, không thể xảy ra tất cả các phần mềm thời gian (do đó danh sách gửi thư comp.risks) và không có lý do chính đáng để bỏ sót các lỗ hổng dễ dàng như vậy.

Cũng lưu ý việc thêm đối số radix vào cuộc gọi parseInt, bạn sẽ không muốn số 0 đứng đầu để tạo ra nhiều thứ lộn xộn. Có, đối số radix là tùy chọn nhưng thực sự không nên và ngón tay của bạn sẽ tự động thêm , 10 vào mỗi cuộc gọi parseInt mà bạn thực hiện.

+1

Câu trả lời hay như vậy: D. Tôi thích sự ngắn gọn của giải pháp thứ hai nhưng cũng giống như "tất cả-là-một biểu hiện" của người đầu tiên. Tôi có thể đề xuất tham gia cả hai [bằng cách sử dụng cụm từ 'swtich '] (http://goo.gl/QKKAq) không? = D (Tôi không muốn ăn cắp bất kỳ điểm nào được đăng tải như một câu trả lời mới) – epidemian

+0

@epidemian: Điều đó có vẻ như là một lựa chọn tốt cho tôi, tôi có nhiều điểm và tôi không ngại chia sẻ vì vậy bạn nên đặt nó xuống một câu trả lời. Tôi có thể sử dụng thứ hai, tôi thích "nó là một bảng tra cứu nội tuyến" có hiệu lực. –

+0

OK, tôi đã thêm câu trả lời dưới dạng phụ lục của bạn. – epidemian

8

Thêm một chút để mu is too short's answer, bạn có thể chuyển đổi đoạn mã thứ hai của mình vào một biểu 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' 

này về cơ bản là tương đương với làm một switch (true) trong JavaScript (mặc dù trình biên dịch CS sẽ tạo ra một switch (false) statement with the negated conditions để đảm bảo kết quả boolean từ các biểu thức ... tôi nghĩ).


Và lý do tại sao switch trên phạm vi không hoạt động là dao động literals trong CS đại diện cho mảng JS cũ đồng bằng (mặc dù trình biên dịch sẽ làm một số thủ thuật tối ưu hóa khi làm một cái gì đó giống như for i in [1..something]), vì vậy khi họ tìm thấy bên trong một switch họ được đối xử chỉ 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"; 
} 

giá trị bên trong tuyên bố switch được về cơ bản so với mỗi giá trị case sử dụng ===, mà chỉ hoạt động cho nguyên thủy, không phải cho mảng (và thậm chí nếu nó làm việc cho mảng, nó sẽ được thử nghiệm bình đẳng mảng, không phải nếu giá trị ed switch được chứa trong mảng case ed).

+1

Hãy xem, đó là giá trị thực hiện. Tôi sẽ không nghĩ đến dạng 'switch' đó nhưng lần sau tôi sẽ làm thế. Tôi nghĩ bạn đúng nhưng ngữ cảnh boolean và sử dụng 'switch (false)' thay vì 'switch (true)'. –

Các vấn đề liên quan