Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
from what i understand so far using twitter as an example, a single tweet would be a model then the backbone view would render the collection of models. So would the model render or would i make a separate view to render that model?
In Backbone.js, there are collections and models. A collection contains more than one model of the same type. If you take twitter as an example, a single tweet may be considered as a model and the the list of tweets can be considered as a collection. Both the collection and model have views associated with them. It is this view that gets rendered and not the model/collection. A view for a collection may contain multiple number of views of the model that it holds. For example, the twitter feed(Collection) on on your Twitter home page is the view associated with the collection of tweets and each block that represents a tweet is the view corresponding to a single tweet(Model)
For example:
A model could be a single tweet.
A collections could be a bunch of tweets.
The render cycle:
User click on "Show me a bunch of tweets".
Your view is fetching the BunchOfTweet collection (it means the collection call the api).
When the collection receive the results (a array of models/tweets) it will tigger an event "change".
your view is listening to "change" for this collection and then trigger the render function.
Ask for new data => Fetch data => re-render
I hope this cycle is clearer now.
Related
I've been learning backbone.js over the past couple of weeks and am about to start using it in anger in an app I'm writing. My question to you is about a use case for models and collections in a Bootstrap 3 navbar.
On my server side I authenticate the user and, based on their profile, assign them a role (author, editor, administrator etc.). I then construct an object that contains the appropriate menu structure for the user's role and pass that to the client using Handlebars. The intent is for the browser to construct the HTML to render the menus according to the properties (key/values) in the object using backbone.
My thoughts are that the navbar itself is a collection of models (navbar); each dropdown menu or link on the navbar is a single model (navbarItem); each of these contains a collection of menu items (navbarItemMembers), these collections being of models of each individual menu item (navbarItemMember). I can then set event listeners against each navbarItemMember to trigger an appropriate route or render action as appropriate.
So, getting to the point... am I over-complicating things? A collection containing models each containing a collection of other models, each of those mapping to a view that renders a on the main page. Seems convoluted to me, but from my (albeit limited) understanding of backbone.js it does seem the right way to do this...?
Advice much appreciated from those more experienced (battle scarred?!) than I. Thank you.
Use a collection when it's going to provide some benefit to you over a plain model. The benefits could be either
Interacting with a RESTful service where you'll want to not just get a list of data but then separately fetch/modify/add/delete individual items is that list
Defining separate Views for each item in the list rather than a having a single View that iterates over the list.
I don't think a basic navbar benefits from either of those. If your navbar has some super fancy elements beyond just links then maybe #2 applies but otherwise keep it simple, use a single model with a single view/template
I have a page which contains two Backbone Views. A view for list of contacts ContactsListView and a view for navigating NavView.
ContactsListView has collection of Contact models. My list of contacts collections is quite bigger so I don’t want to display all of them on page load.
So I have implemented contacts collection to fetch only a range (initially 0 to 50) of contacts from server and ContactsListView displays it. And use NavView to display the range of contacts ContactsListView is displaying currently. It also has next and previous buttons on click of which ContactsListView should display next or previous range of contacts.
Here my NavView is actually controlling what range of contacts ContactsListView should be displaying. But I want to decouple ContactsListView from NavView.
I realized I can do this with creating a Range model (with from and to attributes with default set to 0 and 50) and passing it to ContactsListView and NavView. While ContactsListView adds a listener, ContactsListView.show(from, to), to change event on Range model and NavView is updating the Range model when clicked on next or previous button. As the Range model changes ContactsListView listener would fetch contacts to update it's view.
Or
I can create a Range model and pass it to NavView. NavView then updates the range on click of prev or next button and triggers an event rangeUpdated with range values on (NavView) itself. I add listener on NavView in some additional code piece (probably my own controller object) and invoke ContactsListView.show(from, to) explicitly.
Which one is better way to decouple ContactsListView and NavView? Or is there other way to decouple them?
As long as your question is tagged with backbone.marionette, I assume you are using it, or thinking about using it.
One option could be using the marionette.compositeview, that lets you define both a model and a collection in the same view, so you wouldn't need to share models between views.
But maybe, that could not the best approach if you really want to decouple both views. For decoupling them, your second option using your own controller (or marionette.controller) is the one I like more, as you don't need the range number as explicit data contained in a model within the ContactListView (you already have that information in NavView).
Lastly, I like to do the fetching/saving data from the Controller, and not from within the view. The View in MVC patterns just show things, getting information from the model. Retrieving data from server that will be stored in the model seems more a Controller operation. I don't know how are you binding the data with the view, but maybe the ideal will be fetching the data from the Controller, and let the view render itself when the change of model is detected.
Initialize both views with Range model.
In Contact List view listen to Range model change event to request new data from Contacts collection and show them.
When click on Nav view just set the Range model with new values (it will trigger change event and your Contact List view will be updated).
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I am working on an online html presentation editor that is currently in production.
Eventually, I would like to re-write it using angular, preferably by gradually replacing components of the app rather than rebuilding it from the ground up.
To Start, I would like to implement new features using angular.
In summary, the question is how to handle the case of an application where only certain sections are using the framework?
It seems that the angular app would need to interface with the rest of the app through an api, as if its an external entity.
EDIT for clarification:
the application resembles power-point with a stack of slide thumbnails. The selected slide contents are loaded into an editable work-space, where changes are applied via a menu to the selected element.
I would like to add an audio feature to the menu. It's a form that edits data attributes on the selected element. These data attributes are used to generate an html5 audio element elsewhere.
If I were to build the audio module using angular:
1.The ng-app attribute would have to be on a parent element of both the workspace and the menu.
input controls in the add/edit/remove audio form have to be bound to the same model as the selected element's data attributes.
example:
<input value="{{loop}}">
<div class="element selected" data-audio-loop="{{loop}}">
3.when opening the audio form the angular app needs to be aware of what the selected element is.
4.only this element needs to be bound to the same data as the form.
steps 3 and 4 are where I am not sure about the implementation.
If the entire app was modeled in angular, then step 3 would be easy, because there would be a model that tracks the selected element.
How should the angular module be made aware of what the selected element is, So that it can apply its bindings?
EDIT: (further clarification)
assume I have these elements, only one of which is selected:
<div class="element selected" data-loop="{{loop}}">
<div class="element" data-loop="{{loop}}">
<div class="element" data-loop="{{loop}}">
<div class="element" data-loop="{{loop}}">
and this input:
<input ng-binding="loop">
how can I make the binding only affect the selected element, and not all the elements?
There's no reason not to gradually introduce Angular in your app. If you're currently using JQuery, Angular will use it as well. In not, it will fall back on internal alternative jqlite.
As dabee says, only the code inside the directive ng-app is under control of angular, and you can put that tag on any compatible element (div, ul, etc.) it doesn't have to go on the body tag and control the whole page.
You could encapsulate the interaction with the rest of the app by wrapping data access in a service (a recommend practice in any case) - or through reading & writing to the DOM. In the event that you need to respond to changes in the DOM through actions outside of angular's control, you might want to check the ng-ScrollSpy directive's code for a potential method: An AngularJS module for navigation highlighting
Further reading: http://henriquat.re/directives/advanced-directives-combining-angular-with-existing-components-and-jquery/angularAndJquery.html
Responding to the most recent update:
To make the directive apply only when the class is selected, test for selected in the directive itself. See: How do I apply an AngularJS directive based on a class set by ng-class? In particular, you'll want to extend the function that adds the selected class - it should update a variable that's accessible to angularjs code whenever the element has been updated (or fire an event that you'll handle in the directive code). Create a $watch on that variable (or add an event handler), and apply the dom transformation to add or remove the feature as applicable.
Only the code inside the tag with directive ng-app is under control of angularJS. Thus the remaining code can be control by any other tool.
http://docs.angularjs.org/api/ng.directive:ngApp
On adding new model to my collection I don't want the view to be refreshed but I want the model to be appended to my collection and be appended to the view. SO i shouldn't render the view again. Is it possible via Backbone.js? How should I proceed ?
You could have a view that handles the whole layout, and a view that represents a single model. You would make the render method of the latter to return the HTML of a single model, and append the result to a list using the main view. You have a great example of this in the Addy Osmani's book "Developing Backbone.js applications". Take a look at the section where he explains how he renders each task to the todo list of his Todo App, if I understood well, your problem is solved in there.
I am trying to create a real-time application and there is a collection that I am constantly fetching using setInterval. The problem I am having is that when I fetch my collection Backbone rerenders the whole collection and if I set my fetch interval too short then the events binded to the views associated with the elements in my collection don't fire the click events binded to them reliably (presumably because it was busy rerendering?). How should I structure this?
I'm assuming based on your question that you have a single view rendering your entire collection, bound to the 'sync' event. If instead you create views to render the individual elements of your collection and, on 'sync' iterate through the models in the collection, rendering new ones and updating the views associated with models which have changed you will achieve what I think you want.