I have a marionette layout, which I want to attach directly to the element of the page.
App.Views.Layouts.Unauthenticated = Backbone.Marionette.Layout.extend
template: "layouts/unauthenticated"
regions:
content: "#content"
header: "#header"
footer: "#footer"
views: {}
initialize:->
#el = $("body")
#delegateEvents()
then later in the app, I do this
App.layouts.unauthenticated = new App.Views.Layouts.Unauthenticated()
App.layouts.unauthenticated.render()
The layout is not attached to the page.
How do I attach it to the body, while I already used body as an "el", since I don't need extra wrappers.
You need to set the el in the definition of the view, not in the initializer.
App.Views.Layouts.Unauthenticated = Backbone.Marionette.Layout.extend
el: "body"
template: "layouts/unauthenticated"
regions: ...
Related
This is the code:
NewEntry_CategoryView = Backbone.Marionette.ItemView.extend({
template: "#NewEntry_Category-template",
tagName: "p",
initialize: function () {
$("#sliderContainer").slider();
}
});
NewEntry_CategoriesView = Backbone.Marionette.CompositeView.extend({
template: "#NewEntry_Categories-template",
tagName: "div",
itemView: NewEntry_CategoryView,
itemViewContainer: '#categoryContainer',
appendHtml: function (collectionView, itemView) {
collectionView.$("#categoryContainer").append(itemView.el);
}
});
Why does the jquery ui slider not render when I show the NewEntry_CategoriesView ?
DOM events/manipulation like slide() won't have any effect on the view object's initialization because there is no such DOM element available yet.
Instead, you need to listen to dom:refresh of the view to manipulate its DOM element.
So, just put the code in onDomRefreshin your ItemView
onDomRefresh: function(){ $('#sliderContainer').slide() };
This above is a direct fix. But there are two more things to improve:
Don't call other div outside of this view when possible. In this case, if #sliderContainer belongs to another view, send an event to allow it slide itself. This is not the job of CategoryView. If it is inside current view, refer it with this.$el.find(".some-div") or better yet ui object.
Your collectionView's appendHtml is unnecessary. Marionette also takes of this common case.
I want to do a simple application using backbonejs with mustache template. Can you give me a sample program??
New node file:
var Person = Backbone.Model.extend({
defaults: {
name: 'Guest Worker',
}
});
var PersonView = Backbone.View.extend({
tagName: 'li',
initialize: function(){
_.templateSettings = {
interpolate: /\{\{(.+?)\}\}/g
};
this.render();
},
render: function(){
var template1 = _.template("Hello {{ name }}!");
this.$el.html( this.template1(this.model.toJSON()));
}
});
This is my js code.
Mustache template engine doesn't work this way. Here's a small example from the documentation :
var view = {
title: "Joe",
calc: function () {
return 2 + 4;
}
};
// output will then contain processed html
var output = Mustache.render("{{title}} spends {{calc}}", view);
Anyway, i would recommend you using Handlebars (http://handlebarsjs.com/) instead of Mustache. It's almost the same syntax (and it has partials as Mustache does), but far more powerful thanks to its helpers.
Finally, you should use something to precompile your templates. You can either use handlebars's one (http://handlebarsjs.com/precompilation.html) or another one like Brunch, or Grunt.
[Edit] OK, let's try to elaborate a bit... I won't give you any complete example (i don't have one right now, and it wouldn't teach you anything), but the one i posted above should be sufficient to understand Mustache basics.
Now you have to find a way to precompile your templates, here's an answer with some clues : How to load templates with Hogan.JS from an external file?
While an underscore template is set like this in Backbone.js:
template: _.template(...)
A mustache template is set like this:
template: Mustache.render.bind(null,<template>)
//Mustache.render(template,view,[partials])
//a partial function is created because this.template should be a function
//<function>.bind() creates the partial function
don't do these:
template: Mustache.to_html(<template>) // deprecated
// or
template: Mustache.to_html.bind(null,<template>) // deprecated
// Use Mustache.render() and not Mustache.to_html()
Say I have these two Backbone.Marionette views:
var FooView = Backbone.Marionette.ItemView.extend({
tagName: p,
id: 'foo',
template: this.templates.summary
});
var BarView = Backbone.Marionette.ItemView.extend({
template: this.templates.summary
});
And then I want to show them inside an app region, like so:
App.contentRegion.show(new FooView/BarView());
The first view would create a new element and append it to the region. I thought the second way would be more like a standard Backbone view and attach itself to the region without creating a new element, but it wraps it in a tag. Is there a way to avoid this without using something like setElement()?
For this, you should use the attachView method: https://github.com/marionettejs/backbone.marionette/blob/master/docs/marionette.region.md#call-attachview-on-region
I have a strange trouble, i created a simple view using backbone.js :
class MyApp.Views.Tools.TextBox extends Backbone.View
template: JST['pdfs/tools/text_box']
tagName: "div"
className: "resizable"
id: "resizable"
events:
'click .close': 'closeRect'
initialize: ->
#
render: ->
$(#el).html(#template())
#initDraggable()
this
initDraggable: ->
$(#el).resizable().draggable();
#$(#el).css({"position": "absolute"})
#
closeRect: (event) =>
console.log "pass"
And my template:
<div class="close">x</div>
<input type="text" name="text_' + #count++ + '" />
When i do the line : $(#el).resizable().draggable();, jQuery add me a style="position:relative" to my element. I know why when i look the Draggable function on jQuery UI:
if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position")))
this.element[0].style.position = 'relative';
But i don't understand why this.element.css("position") doesn't return my css property on the element : position:absolute.
Is it possible Backbone.js load javascript before css or doesn't use the css of my page?
But i don't understand why this.element.css("position") doesn't return my css property on the element : position:absolute.
I'm confused; as you pointed out jQuery draggable adds a position: relative style to its element. Then, you had set it back to "position": "absolute" ... but you commented it out.
#$(#el).css({"position": "absolute"})
So, it seems like the reason it's still relative is that jQuery change it to relative and you never changed it back.
is there a way to specify a template for marionette region?
right now i'm using the layout object to specify a template.
AppLayout = Backbone.Marionette.Layout.extend({
template: tmpl
});
var layout = new AppLayout();
App.main.show(layout);
App.addRegions({
userInfo: "#userInfo",
mainMenu: "#mainMenu",
content: "#content"
});
App.mainMenu.show(new mainMenuView.Views.menu());
App.content.show(new dashboard.Views.main());
why i cannot get access directly from my app object to my regions, when i define them inside the layout object?
AppLayout = Backbone.Marionette.Layout.extend({
template: tmpl
regions: {
userInfo: "#userInfo",
mainMenu: "#mainMenu",
content: "#content"
}
});
var layout = new AppLayout();
App.main.show(layout);
does not work:
App.mainMenu.show(new mainMenuView.Views.menu());
App.content.show(new dashboard.Views.main());
Thanks
is there a way to specify a template for marionette region?
This is exactly a Layout - a rendered template with regions in the rendered output.
why i cannot get access directly from my app object to my regions, when i define them inside the layout object?
The regions in a layout are scoped to the layout's el, the same as events. Even if you have a region defined as a "#id" selector, it is still scoped to the layout and will not find anything outside of the layout's el.
Also, defining a region on a layout adds the region to the layout, not the application object. If you want the regions defined on the application object, you have to add them to the app object directly.
To access the regions of the layout you put in a region, you can write:
App.main.currentView.mainMenu.show(someView)
App.main.currentView.content.show(anotherView)