Ylan, Glad you found a working solution! Yeah, my comment about "index.js.erb" containing only JSON was meant to point out that the logic of where the content goes should not be in the rendered view, but in the calling view. Whether you put actual JSON in "index.js.erb" or HTML, XML, base64-encoded Klingon, doesn't really matter. It's all about the separation of logic from templates, which is why I love MVC.
Good luck! - Adam On Tue, May 10, 2011 at 10:09 AM, Ylan <[email protected]> wrote: > > On Monday, May 9, 2011 6:04:45 PM UTC-7, Adam Grant wrote: >> >> Hi Ylan, >> >> So, I think you are correct about code smells, but not in the same way I'm >> thinking. A couple of things stand out to me as worrisome for long-term >> maintenance and architecture. Here are some suggestions: >> >> 1) Make your index.js.erb views ONLY contain JSON. The Rails community >> and examples, for some reason, love to put logic in your javascript views to >> update the page it's being rendered into. I think that is BAD! If you GET >> /users?format=js, it should return to you the JSON form of the user objects, >> and should know nothing about what your client-side app wants to do with >> that information. Your /users?format=html page should be responsible for >> AJAX GET-ting the JS formatted version of /users and updating the HTML >> element you want in a "on success" callback (in whatever lib you are using, >> like JQuery). That logic should NOT be in the JS view you are rendering. If >> you want to use that same /users?format=js call in a REST-ful client that >> doesn't have a web browser component, how are you gonna parse that info? It >> doesn't make much sense. That way of doing it limits the potential benefits >> of the different view formats. >> > > I know whre you are going with that, but in my case, what I am really using > the js responses is to generate html that will get inserted into an existing > html page. If I went the pure JSON route, then I would need my client-side > javascript to know how to render the response into html, which seems a > little too much, since erb (actually haml) does a wonderful job of doing > that now. > > >> >> 2) Wrap your pagination AJAX calls in a main, common javascript file that >> gets included in each index view (or in your main layout), and in your >> index.html.erb views write the specific code to implement it: >> >> ============================= >> # public/javascripts/app/pagination_helper.js >> var PaginationHelper = function (new_url, div) { # Notice the >> namespace of "PaginationHelper"? DON'T create global JS functions! >> var url = new_url; >> var div_to_update = div; >> >> var get_page = function (page) { >> $.get(url, {success: function (result) { >> $('#'+div_to_update).html(result); } }) # <== Highly paraphrased here. >> Assumes jQuery. >> }; >> >> return { >> initialize_pagination: initialize_pagination, >> get_page: get_page >> }; >> } >> >> # app/views/users/index.html.erb >> <div id="users"> >> <%= render @users %> >> </div> >> >> <script> >> document.ready(function () { pagination_helper = new >> PaginationHelper('/users', 'users') }); >> </script> >> >> ================== >> >> You can then program (ie: update the partials) the pagination links to >> call "pagination_helper.get_page(<page_num_of_link_clicked_on>)", which is >> already initialized to point to the URL you want when the /users page is >> loaded, and will update your div with the results returned. >> >> Now, I realize that code probably doesn't work, but that's how I've >> designed other pagination pages before. This way, you can reuse >> PaginationHelper everywhere, and each index page will just initialize it >> with the correct URL the pagination links need. This offloads the burden of >> WHERE to render things onto the HTML index page, not the JS page! >> >> You can also make that "document.ready" code a partial that takes local >> vars for the url and div_to_update, and then put that one partial call in >> all your index views with the appropriate mods to those values. >> > > Thank for the example: I think that is very applicable solution to my > problem, and it did give me many ideas. What I have now is this: > > #index.js.erb > <%= render 'shared/pagination %> > > #_pagination.js.erb > $('#<%= controller.controller_name %>').fadeOut("fast", function(){ > $(this).replaceWith("<%= escape_javascript(render(:partial => > controller.controller_name)) %>"); > $(this).fadeIn("slow"); > > Basically, each resource's index.js.erb will be the same and the pagination > partial leverages the naming convention for views, models, controllers. I am > keeping the convention in all my resources, so I think this works. > > > >> >> Also, this is a sweet jQuery extension library that takes little effort to >> implement, and basically works this same way: >> >> http://www.datatables.net/ >> > > That is pretty cool. I'll keep that in mind as well, if I need more > interactive tables later on. > > Thanks for the help! > > -- > Ylan > > -- > SD Ruby mailing list > [email protected] > http://groups.google.com/group/sdruby > -- SD Ruby mailing list [email protected] http://groups.google.com/group/sdruby
