I have the basic scenario on a Dojo 1.9 + Dijit web application:
Request JSON data over the network
On the the successful reply I parse the JSON data and save to the application model
The UI watches the model and when there's data, it creates new Custom dijit/_WidgetBase instances to show the data.
Every Custom Dijit Widget is inserted to a dijit/layout/LayoutContainer via myLayoutContainer.addChild(customWidget);
Everything works fine but I would like to improve the rendering performance.
I noticed that dijit/layout/LayoutContainer is a dijit/_Container and has its own addChild() which uses dojo/dom-construct.place() which changes the DOM directly.
So I guess I could save some milliseconds if I add all my customWidget instances to a Document Fragment and then add it to the LayoutContainer with just one call to addChild().
But dijit/_Container.addChild requires a widget of type dijit/_WidgetBase so the Document Fragment approach wouldn't work.
How could I achieve my goal?
You could create a single "container" widget which contains all the logic to create the child widgets and attach it to itself. Then only add the single "parent" widget to the LayoutContainer. If you wanted to do even less you could just use a ContentPane as the "container" widget.
var contentPane = new ContentPane();
//multiple times
contentPane.addChild(...)
/layoutContainer in the page flow
layoutContainer.addChild(contentPane);
I can't comment as to how this would change performance though.
Related
I'm aiming for a decoupled UI architecture. I want the carousel and pagination components to be separate from each other; but with the pagination able to listen for changes on a uiCarouselMoved event.
Example: http://jsbin.com/uQadehI/1/edit?html,js,output
The problem arises when I have two instances of carousels and pagination respectively. I'd like to be aware of the best design pattern within Twitter Flight to handle a 'bridge' between the Carousel and the Pagination components, without relying on irrelevant logic such as DOM tree structure, and preferably no hard-coded IDs.
So, is it possible to know which pagination to updated, based on the source carousel?
Creating a pagination mixin and mixing it in to the carousel would seem to make sense.
Another option is to use the DOM to provide structure. By attaching an instance of pagination and carousel to the same DOM node or tree, you create a non-declarative relationship between the two.
Alternatively, generate a unique ID (using, for example, _.uniqueId http://underscorejs.org/#uniqueId) and pass that with the data from the carousel. This can also be included in the response, allowing components to determine if they are interested in global events.
TweetDeck uses all three of these methods in various instances. Using the DOM for structure requires no extra boilerplate, though it is also the most implicit relationship. Using IDs is very specific but requires extra boilerplate in event triggers and handlers. Using a mixin requires no boilerplate and is very specific but does create a dependency, which you may want to avoid.
I would make pagination and carousel both mixins, with_carousel and with_pagination respectively, instead of individual components. This will allow you to use both within the same component, and attach that component to a new outer level dom node. This will allow you to listen for the uiCarouselMoved event locally instead of attaching the listener to the document.
An example is here:
http://jsbin.com/iZeLABAW/1/edit
I would like to simulate some sort of drag and drop to delete capability on my site (like the recycle bin/trash on windows/osx)
I have a bunch of objects in the database that are being represented by ruby as div on my site.
I know I can add a drag capability to each of the divs using jquery, but I am not sure what to do afterward.
How do I assigned a specific area (an image) to initiate the destroy command? Since each object has a unique id the destroy should come from the object , but should be triggered by the trash image
Do I need to render my UI after such an action or would rails take care of it, like it does now with the regular destroy that comes in scaffolding ?
I know that it is a bit of an abstract question, but I am still in the design process and haven't written much code.
Since you mention jquery, I'm guessing that you're using the Draggables from jQuery UI. You should also look at the docs for Droppable, which details how to handle drop events. After you catch the drop event you could either do a full page post to your server, which would refresh the page and update the UI, or you could make an AJAX call and update the UI via JS.
I'm building my first Backbone Marionette application, but I'm confused how to add reusable UI to my view templates, where those UI elements have JavaScript interaction.
I have built a number of UI elements like the input element shown below. This input element can be interacted with via JavaScript, for example by clicking the up/down arrows to change the input's value.
These UI elements should be reused again and again in multiple views, and there can be many instances of these UI elements contained within any given view. A mockup for one such view, containing several UI elements, is shown below.
A model for this view might look like this, and I would like to have the JavaScript interaction of my UI elements interacting with this view's model. In other words, the JavaScript interaction on a UI element will have to be able to pass an event to the model of the view inside which the UI element is shown.
var fontStyles = Backbone.Model.extend({
defaults: {
fontFamily: "Helvetica Neue",
fontWeight: "Regular",
color: "rbg(1,197,255)"
...
}
});
My Question
For a properly structured Backbone Marionette application, where would I define these reusable UI elements and their JavaScript interaction methods, in such a way that I can reuse them throughout all of my views/modules?
As another concern, will it be possible to write the HTML for these UI elements once, in a template file, and then reuse that single UI template file again and again in the underscore templates of my views? Or will I have to repeat the HTML for my UI elements in the template of every view?
Thank you for any help, and if my question is unclear please let me know.
You should create this elements as Marionette.ItemView's extensions
Each item view should be created and placed into region inside layout you want to use them
And of course, since it is ItemView it contains template:some_template,
Or Marionette.Layout extensions if they by itself also contain regions
So, as for your pictures
Small picture is ItemView
Big picture is Layout, which contains number of regions, each region contain widget, which is ItemView.
Layout receives model:some_model on initialization (Layout is extension of ItemView)
I have developed a large "single page application" using jQuery and jQuery UI. As I load various sections in the app it creates jQuery UI widgets like dialogs or date pickers. They tend to hang around and cause some issues when I reload certain sections. I would like the ability to call a function that destroys all jQuery UI widgets that have been loaded and remove them from the DOM. Any solution to catch all of them? Thanks!
In theory, it's easy enough to locate and destroy all widgets of a specific type on a page:
$(":ui-draggable").draggable("destroy");
So, it isn't unthinkable to create a loop around an array of widget types you know you're using, and delete every kind of widget on the list.
Use remove() or detach() to clear the contents of your jquery UI widgets and here is the difference
remove() removes the matched elements from the DOM completely.
detach() is like remove(), but keeps the stored data and events associated with the matched elements.
In my mobile website, I dynamically create a form in javascript, so I need the 'reload' the page to get the jQuery Mobile style.
For a listview, we can simply call $("#mylistview").listview("refresh") but there is no such feature for form.
I know that we can call "refresh" one each element of the form, but by doing this, the style is not correctly applied. Indeed, all my checkbox get separated, they don't appears in one "inset"
I there any workaround ?
Docs in the release notes:
http://jquerymobile.com/blog/2011/08/03/jquery-mobile-beta-2-released/
Example:
$('#nameOfPage').trigger('create');
Quote:
New “create” event: Easily enhance all widgets at once
While the page plugin no longer calls each plugin specifically, it
does dispatch a “pagecreate” event, which most widgets use to
auto-initialize themselves. As long as a widget plugin script is
referenced, it will automatically enhance any instances of the widgets
it finds on the page, just like before. For example, if the selectmenu
plugin is loaded, it will enhance any selects it finds within a newly
created page.
This structure now allows us to add a new create event that can be
triggered on any element, saving you the task of manually initializing
each plugin contained in that element. Until now, if a developer
loaded in content via Ajax or dynamically generated markup, they
needed to manually initialize all contained plugins (listview button,
select, etc.) to enhance the widgets in the markup.
Now, our handy create event will initialize all the necessary plugins
within that markup, just like how the page creation enhancement
process works. If you were to use Ajax to load in a block of HTML
markup (say a login form), you can trigger create to automatically
transform all the widgets it contains (inputs and buttons in this
case) into the enhanced versions. The code for this scenario would be:
$( ...new markup that contains widgets... ).appendTo( ".ui-page"
).trigger( "create" );
Create vs. refresh: An important distinction
Note that there is an important difference between the create event
and refresh method that some widgets have. The create event is suited
for enhancing raw markup that contains one or more widgets. The
refresh method that some widgets have should be used on existing
(already enhanced) widgets that have been manipulated programmatically
and need the UI be updated to match.
For example, if you had a page where you dynamically appended a new
unordered list with data-role=listview attribute after page creation,
triggering create on a parent element of that list would transform it
into a listview styled widget. If more list items were then
programmatically added, calling the listview’s refresh method would
update just those new list items to the enhanced state and leave the
existing list items untouched.