2016-05-13 10 views
8

Ich habe ein modales Formular über Javascript gerendert. Das Modell heißt Buch.Render Javascript von mehreren Orten: Die Schienen Weg

# controllers/books_controller.rb 

def new 
    @book = Book.new 
end 

def create 
    @book = Book.find(params[:id]) 
    @book.save 
end 

Statt die neue und bearbeiten html zu haben, benutze ich Coffee:

# views/new.js.coffee 

CustomModal.open "<%= j render('books/modal_form', book: @book) %>" 

-

# views/create.js.coffee 

<% if @book.valid? %> 
CustomModal.hide() 
# Other callback scripts for showing alert, etc 
<% else %> 
# Script for showing errors in the modal 
<% end %> 

und die Verbindung zum Auslösen des modal:

= link_to "Create Book", new_book_path, remote: true 

Jetzt ist das Problem, das ich gegenüberstelle, dass dieser Link nur auf der Listenseite des Buches verwendet wurde. So hat der js-Callback beim Erstellen des Buchs eine Warnung ausgelöst und die Liste mit den Änderungen aktualisiert.

Jetzt muss ich diesen Knopf auf einer anderen Seite hinzufügen, wo es keine Liste gibt, also brauche ich einen anderen Rückruf (egal welche Rückrufe wirklich).

# views/create.js.coffee 

<% if @book.valid? %> 
CustomModal.hide() 
# if the list exists 
# show alert 
# update lists 
# else 
# do different things 
# end 
<% else %> 
# Script for showing errors in the modal 
<% end %> 

Es scheint etwas schmutzig, aber es ist nicht so schlimm:

Also, ich mag zum create.js.coffee etwas hinzugefügt hatte. Das Problem ist, dass ich jetzt mehr als 3 Bedingungen habe, weil die Schaltfläche "Create Book" mehrmals in der Webapp verwendet wird.

Also, irgendwelche Ideen über ein Design-Muster dafür?

+0

Ich mag den Ansatz der Rückgabe von Coffeescript. Es hat ein gutes Gefühl und ist ein bisschen statisch dynamisch. Wenn Sie nach "Ideen zu einem Designmuster dafür" fragen, was genau suchen Sie in einer Antwort? –

+0

Ich bin auf der Suche nach einem Muster, das alle verschiedenen Möglichkeiten leicht zu pflegen, etc. –

+0

Wie wäre es mit dem eigentlichen Skript, sondern nur Callback aufrufen, die auf jeder Seite unterschiedlich definiert werden könnte, wo Sie den Link benötigen? Etwas wie: Wenn Rückruf definiert ist, rufen Sie den Rückruf sonst die Standard-Zeug – michalvalasek

Antwort

0

Sie könnten in Betracht ziehen, die Erfolgs-/Fehlerlogik im Controller beizubehalten und stattdessen separate Sichten zu verwenden, die auf Erfolg/Fehlschlag basieren. So haben Sie dann eine create_success.js.coffee und eine create_error.js.coffee. Jeder kümmert sich nur um seine eigene Situation und kümmert sich nicht um die andere. HINWEIS: Dies ist Pseudo-Code.

# controller 
def create 
    @book = Book.find(params[:id]) 

    if @book.save # save will run validations 
    render :create_success 
    else 
    render :create_error 
    end 
end 

# Views 
# 
# create_success.js.coffee 
CustomModal.hide() 
# other stuff you do if successful 


# create_error.js.coffee 
# re-render form with errors 
# assuming the modal is already open, you might want to just replace the form, rather than re-open the modal. 
$(".myFormSelector").html("<%= j render('books/modal_form', book: @book)%>") 
1

Was Sie tun, ist nicht schrecklich, aber Sie könnten ein paar Dinge, um es ein wenig aufzuräumen. Ich würde empfehlen, die Geschäftslogik aus der Ansicht und dem Controller zu entfernen und stattdessen das Presenter-Muster und die Helfermuster zu verwenden. Diese Muster sind ziemlich gut in diesen Tagen dokumentiert und haben eine Reihe von Vorteilen, einschließlich:

  • Förderung dünne Controller
  • Förderung kleiner, kurze Stücke von Code
  • das Gesetz der Demeter Förderung
  • Unit-Tests machen leichter

Hier ist eine ziemlich gute Beschreibung des Presenter-Muster ist: https://gist.github.com/somebox/5a7ebf56e3236372eec4 oder: 012.http://eewang.github.io/blog/2013/09/26/presenting-the-rails-presenter-pattern/

Im Grunde funktioniert es so, dass Sie Ihre Geschäftslogik in eine separate Klasse namens "Presenter" verschieben. Diese Klasse enthält die Logik, die Sie normalerweise in Ihrem Controller behalten würden.

Helfer sind auch ziemlich gut dokumentiert und arbeiten auf die gleiche Weise, aber für Ansichten.Helfer sind viel einfacher zu testen als Logik in Sichten. Für weitere Informationen: http://api.rubyonrails.org/classes/ActionController/Helpers.html

Es könnte wie folgt aussehen (bitte beachten Sie, dass dies nur ungetestet ist, ‚pseudo‘ Code, den ich bin mit dem Muster zur Veranschaulichung):

# app/controllers/books_controller.rb 
    helper BooksHelper 

    def create 
     book = Book.find(params[:id]) 
     book.save 
     @presenter = BookPresenter(book) 
    end 

    # app/presenters/book_presenter.rb 
# move your 'fat' controller logic here 

    class BookPresenter 
     attr_reader :book, :page_type 

     def initialize(book, options={}) 
      @book = book 
     end 

     private 

     def page_type 
      # custom code here for determining page type 
     end 

     ... 
    end 

# app/helpers/books_helper.rb 
# move your view logic here 
module BooksHelper 
     def custom_modal(book_presenter) 
      if book_presenter.book.is_valid 
       handle_valid_book(book_presenter) 
      else 
       # handle invalid book 
      end 
     end 

     def handle_valid_book(book_presenter) 
      custom_list_modal if book_presenter.page_type == 'has_list' 
      custom_listless_modal if book_presenter.page_type == 'listless' 
      # other conditions 
     end 

     def custom_list_modal 
      # modularized JavaScript for pages with a list 
     end 

     def custom_listless_modal 
     # modularized JavaScript for pages without a list 
     end 

     ... 
    end 

So in dieser In diesem Fall kann die Geschäftslogik in Ihrer Anwendung mithilfe von RSpec oder einem anderen von Ihnen verwendeten Testframework problemlos getestet werden. Die Komplexität von JavaScript wird reduziert und das Testen wird einfacher. Ihre JS-Ausgaben können bei Bedarf in verschiedenen Teiltönen getrennt definiert werden oder Sie können den eigentlichen JS-Code von Ihrem Hilfsmodul zurückgeben. Es ist ein komplexes Muster, das zuerst angenommen wird, aber im Laufe der Zeit wird sich alles natürlicher, modularer und einfacher zu pflegen anfühlen.