I'm starting to learn Backbone.js and can't figure out one thing: In a typical rails app, I have a layout view and a nested view. My layout usually contains navigation links that are processed by rails routing.
How do I do the same with Backbone? I'm using Rails 3.2 and eco templates.
Should I create nested templates in eco?
Should my navigation links be plain html links with a href or should the navigation be event driven?
For example I have a list of categories on the left, and a category items on the right. I want my categories to be shown on every view and the corresponding category items (with a URL in browser corresponding to selected category) too.
Please point me to right direction, because most tutorials on the Web are 'todo' style applications with no navigation at all.
Thank you.
UPDATE
Turns out, my question wasn't clear, so let me narrow it down.
How can the concept of RoR layouts be applied to backbone.js applications?
And I'm curious about two possible ways of navigation:
create
%a{:class => "customers", :href => "#customers"} Customers
handle ".customers click" event in my view
Which way is better?
And I'm curious about two possible ways of navigation:
create %a{:class => "customers", :href => "#customers"} Customers
handle ".customers click" event in my view
Which way is better?
neither is better until you know the specific context in which you are working. they are simply options for achieving your goal and desired functionality.
there are times when both should be used, as well. for example, if you are supporting search engine optimizations and accessibility.
Here are some better questions to ask:
Which of these will be the simplest thing that can get the job done? will it be more code to write the route handler, or the click handler?
Will the route handler tightly couple the functionality to a router, when I don't need that?
Do I really need a route for this link, so that people can bookmark it and come back to it directly?
Will a click handler cause my code to jump through several hoops of calling other objects that aren't directly related, or can I use a simple event to cause the other objects to run?
There isn't a single correct answer to any of these questions. I recommend trying many different ideas when you can. Keep in mind that you will likely change your answer as you develop new features. The answer that you want, today, won't be what you need tomorrow. But that shouldn't stop you from picking an answer now and moving on. Pick one, put it in place, and when you need to change it, change it.
Related
Im just starting with famo.us and javascript. And i really need some help with the views in famo.us.
Could you please tell me how you close a View ? How does your code look like ?
Is it true that if I have a view in a view in a view, I have to pass the events from view to view ?
Im sorry for my english.
Views in Famo.us are abstract classes. Surfaces are the only actual elements. Views are just there to make things easier and more composable.
Views themselves cannot be closed. You need to use a RenderController if you want to hide something and show something else. There are some hacks to hide something completely, but I would recommend you not go down that line.
If you have a view inside a view, YES you need to pass events from view to view. Unlike Backbone.js no events are EVER bubbled automatically. So you can set up .pipe to connect up events in all cases.
It's also important to note that the design pattern in famo.us is to have two eventEmitters per view. One for incoming events and one for outgoing events. You don't have to follow this design pattern yourself, but it is important to understand it for a deeper understanding of the framework.
Iām new to Knockout JS. Should I use sammy.js to help me with the below?
I am building a Knockout JS App (single page) where as I move from state to state, exactly what sub panels are visible and what they do changes. For example:
pre-login, I have one big panel that invites the user to login.
Right after login, I have a bunch of tabs, a main area for searching and an advertisement at the bottom.
If the user does a search, then I end up in a state where we see tabs, a search area and a search results area.
I imagine doing this via having a state machine that moves from state to state as the user clicks, sort of the way a parser would move from state to state.
I imagine delegating to the current state, an object hanging off of the ViewModel (perhaps) so that my 20 or so different states are almost like 20 very simple different UIs each one separate from the others and simple and clean and easy to understand.
1 - How would I do this, have the UI delegate a sub UI to a sub object hanging off the ViewModel?
2 ā Is there a better way to keep my UI simple even though it has lots of states and different states often look very different from one another in terms of what elements (sub panels) are visible?
3 ā Does anyone have an example were the code repeatedly delegates to a sub user interface?
Am I making sense?
A framework that would probably fit very well is machina.js - should be just what you are looking for.
Here is a presentation on it from jQuery UK - stateful machines
I'm using a scheme where I simply have two separate state observables - one for the total application state and one for the current "page" (tab, or whatever a "page means to you). In coffeescript, as an example:
#currentState('logged-in')
#currentPage('page-foo')
#applicationState = ko.computed => "#{#currentState()}:#{#currentPage()}"
then in your knockout visible bindings, you can match on a specific state or substate:
<div data-bind='visible: applicationState() == "logged-in:page-foo">
or you can do partial matchs:
<div data-bind='visible: applicationState().endsWith("page-foo")'>
I'm thinking about the optimal way to structure my Backbone application. The problem is that I have various complex states, each made by some views showing while all the others are hidden.
What is the canonical way to handle this in Backbone? Two things that I've thought are either controlling the state by the router (calling views hide / show methods) or making the views listen for route event.
The problem with the first method is that the router must be aware of all the views existing in the application.
The problem with this second solution is that I have to make all the views listen to all the events and hide for any of them but a couple that make them show.
Thanks for pointing me to a lean solution.
I use a FSM machine to change the state of the application. Each states shows and hides the appropriate view. My views use transition to animate in and out, so changing the state is more complex, then simple show/hide - it animates in and out from one state into another. I have forked https://github.com/fschaefer/Stately.js to fit my needs.
I can share my personal experience with such a problem. I don't know if it's the best solution, but it worked for me.
My problem was even worse because I had several routers and each of them should hide/show views that belong to it. The solution I chose was similar to the first option you consider.
In my router there is an array which holds all existing views. When the state changes and route callback executes all other views are hidden with this simple code view[i].hide() and the proper one is shown. You can make View model and Views collection if you would like to have more control.
I think it's a better solution, because when you add a new route, you don't have to add route events to all views. Moreover, your views stay decoupled from the router, they may even don't know it exists.
So you have one list and another. One is used for navigation, the other meta data.
Now, the idea is that a user will be adding, reordering, and deleting items in the nav list, and the meta list should be updated to reflect what's going on in the nav list. By adding an item to the nav list, a chunk of HTML is appended to the meta list.
Keep in mind I'll be using jQuery.
So the thing im questioning is the best way to establish relationships between the sets of elements. Now I realize I can use indexes and :eq() etc, but in a complicated implementation with lots of containers, things can get hairy... and coming back months or years down the road to do maintenance could be painful.
Just wondering if people had suggestions for establishing clear relationships. Storing id's in hidden fields? Some kind of master array?
The way you are thinking about this will likely produce some spaghetti looking code. I highly recommend you take a look at an MVC framework like backbone.js < http://documentcloud.github.com/backbone/ > Backbone has a powerful event model that will make it easy for one chunk of UI code to broadcast events to other chunks of UI code.
Using backbone, you could use a model to track the state of your items. You can then have modular views "subscribe" to add/remove/change events on the model.
Backbone literally was built to solve the problem you are facing with your app: "how do I keep track of the state of all of my objects? When they change, how do I track the subsequent UI changes?"
Hope this helps
Hrm, I think you might be making this more complex than necessary. If you have the DOM part keeping track of what the user sees, and the JS object tracking it in code, why do you need a second JS object?
In fact, I would suggest trying to drop the JS object entirely, and keep track of everything in the dom, and only turn it into JS when you need. Unless there is a compelling reason (sometimes performance is the reason - manipulating the DOM is the biggest killer in JS).
Perhaps I am missing something in your use case...
I'm coming across a bit of an awkward problem. I have a Web page with quite a few buttons on it that need to be disabled and enabled at various points. Now if this were a Swing (or any otehr desktop UI interface for that matter), it would be quite trivial: I would simply add listeners for the model changes I was interested in and update the UI accordingly.
This is basic MVC stuff really.
Thing is, I'm at a bit of a loss as to how to handle this nicely in Javascript. I'm going down a route that will end up with some real spaghetti code where the click listeners for the buttons are updating the UI controls and that's just not going to end well.
EDIT: Let me give you a more concreate example.
Example
Imagine a screen that lists open orders. Those orders are presented in a table as each row (order) has multiple attributes against it, such as who is currently managing the order, who made the order, what it's for, when the order was made and the status of the order.
I've done it so you can select one (or more) of these orders by clicking on the rows. This adds a "selected" class, which changes the styling, much like a list.
As to the behaviour, if a user selects one order then certain actions become available, such as Open Order (to view the details), Take Owneship, Cancel and so on. The attributes of the order may also affect what actions are available eg if the order is "owned" by somebody else already, certain actions will be disabled.
Some of these options (like opening the order) aren't available if you've selected multiple orders.
Additionally via a background Ajax call the list refreshes with new orders periodically. The user can also click refresh or can filter the orders (by name, date range and so on) and then reload the orders. While the orders are reloading certain buttons get disabled.
I was going to do a second example but I think that one is sufficiently complex to illustrate the kind of problem. Now I've started this by giving various controls classes. For example, elements with the "select" class might be disabled/enabled/styled when an item is selected.
Now this works reasonably well in simple cases but I'm running into problems where the state of a control depends on multiple conditions. Also the classes are getting fractured by things like some elements want to be styled, some controls want to be disabled/enabled and in some cases both things need to happen.
In Swing I tended to handdle this kind of thing by having a sort of updateUI() method, which would be called whenever the state of a relevant control or model was changed. It would then set the state of all the controls explicitly. Now this is arguably not the most efficient way (eg if you have 30 controls and only need to update one of them it's a bit of a waste) but I found the simplicity was worth it. The alternative was that controls/models ended up with too information about what controls they depended on or those that depended on them. It go tmessy from a coupling point of view.
But I have no such (obvious) mechanism in Javascript. Inobtrusive Javascript as advocated by jQuery is great because it stops random code snippets being littered throughout your code. But I need to go a step further nad have some way of managing the complexity of this (because it is quite a complex screen and will only get more complex).
If you want to preserve your sanity, use a state machine.
You don't really give details about what your UI does, so I'll make up an example. Let's say you have a file upload page. The user should be able to select a file, click an upload button, and then be returned to the page they came from, when uploading is complete. So you could have three states, "SelectFile", "Uploading", "Finished". In the "SelectFile" state, controls should be enabled to allow the user to select a file. In the "Uploading" state, these control should be disabled, and the user should see a progress indicator. In the "Finished" state, the user should be redirected.
Of course, it sounds like your case is more complicated, but the same ideas will apply. You may need more than one state machine, if portions of user interface interact. That's fine.
When you want to change the enabled/disabled elements on the user interface, you just change the state of the state machine. The state machine itself tells the various user interface controls to update themselves based on the current state. You can use a Bharani's (good, up voted) suggestion of using classes to do this. Or whatever mechanism works for you.
The nice thing is that the controls no longer interact with each other. They only interact with the state machine. So you get rid of all the cases where states bounce around incorrectly or endlessly recurse.
Assign specific class names to the divs. That way even if they overlap in functionality you can simply keep adding class names to the div and because of the chain nature of jquery all registered event handlers will be executed.
For controlling form elements during ajax call - you can add ajaxStart and ajaxEnd or you can use ajaxComplete and handle all your code inside the callbacks.
I think i get your problem. I have worked on such screens before and i always ended up refactoring to structure the code better. But at times it will be easier if you could re-organize the functionality itself so that you don't have to handle all things in one place. I think GUI should also be treated like a function - do one thing and one thing well.
I think data modeling is important for JavaScript apps. I am working on this scheduling project for medical clinics and I have a JSON data structure that models chairs/patients in an office. Ember updates the views (UI widgets) automatically when the business logic changes in the models. So right off the bat a lot of sphagetti code is eliminated. If you are doing something graphically intense with user interaction it is almost a crime not to use an existing MVC pattern or to create your own MVC JS classes. The structured discipline is off putting at first but when you see later how it lowers your blood pressure and makes maintenance so much more enjoyable it is worth it. I wouldn't use it for simple one-off projects if they are small. It is better for medium complexity or advanced complexity. Anything that will take me more than a week I will use Ember. I have used knockout.js and Angular and I really like Ember with its Handlebars templating syntax. Easy on the eyes and efficient.