Does Backbone need Underscore? - backbone.js

Due to the
Backbone.js: `extend` undefined?
and my own errors after comment underscore.js :
Does Backbone need Underscore?
Need Partly? (which parts?)

Yes. Backbone has an explicit dependency on Underscore, it says so right at the top of the Backbone page: http://backbonejs.org/
Backbone's only hard dependency is Underscore.js ( >= 1.4.3).

Related

jQuery do not have scope in Marionette module

I tried to create a Marionette module. When I access the template using jQuery in the module, it returns undefined. It happens for with or without default 6 arguments.
Note:
in the main.js this variable returns properly only in the module it returns undefined.
//App.module("LineModule", function(LineModule, App, Backbone, Marionette, $){
App.module("LineModule", function(LineModule){
console.log('LINE DRAFT : ' + $('#line-grid-content-template').html()); // undefined
});
What could be the reason? how can I fix it?
Thank you.
This will normally happen if #line-grid-content-template has not yet been added to the DOM. A few places to first check are, make sure it has the right ID (it's not a class or a miss spelling) and also that who ever is responsible for rendering the div has rendered it before you try to access it via the jQuery selector.

Pass Angular html template to backbone template

I'm trying to slowly convert a Backbone App to Angular. It's actually using Marionette to be precise. In each of my current Marionette views, they are a Marionette.ItemView. For the template to show, I do this:
get template() {
return _.template(nameOfMyTemplate, { myModel: this.model });
}
nameOfMyTemplate would be my AwesomeTemplate.template.html file that is in my solution.
I was wondering how I could go about just passing my template.html without calling _.template in a backbone or marionette app? So somewhere in my backbone view or marionette.itemview, I could do
template: NewAwesomeAngularTemplate.template.html // where NewAwesomeAngularTemplate.template.html is a file in my solution
Has anyone come across this yet? I wasn't able to find much info on how people were converting their apps to Angular from Backbone or Marionette. Thanks in advance!
Marionette expects all templates to be immediately available, not having to be fetched async. The view.template function can be easily overwritten but it needs to immediately return a string (or return a function that will immediately return a string).
There was an old fork called Marionette.Async which enabled fetching of templates on-demand but it was abandonded long ago after the maintainers determined it to be A Really Bad Idea.
Your best bet is to build a mechanism that either loads all the templates into memory up front (like embedding them in a single JS file or the main HTML page) or a custom mechanism that ensures templates are fetched as-needed before the view gets used. The former will be much easier but viability depends on how many templates you have and how big they are.
Not too familiar with Backbone or Marionette, but went over and looked at the website.
I am not sure if this is what you are asking, so excuse me if I am way off base. In Angular you can use the ngRouter or the more powerful uiRouter to bind your urls to controllers and views.
state('index', {
url: "/",
controller: 'SomeController',
templateUrl: "template/NewAwesomeAngularTemplate.html"
})
Not sure if this is what you were looking for. If so, check out the documentation at https://github.com/angular-ui/ui-router
You can use the grunt ts html2ts support : https://github.com/grunt-ts/grunt-ts#html-2-typescript-support
It turns an html file into a typescript string variable which you can return from the template function.

Jade Mixins in AngularJS

Hi I would like to implement Jade templates in my AngularJS project, and have mixin in my template (reusable code).
However the problem that I am facing is that we cannot use Mixin with arguments. Am I doing it correctly or is there any alternative for the same in AngularJS that I am missing?
You can create an js object from your model and pass it as strings to the mixin like the following:
+avatarRow({name: '{{avatar.name}}', uuid: '{{avatar.uuid}}', verificationCode: '{{avatar.verificationCode}}', status: '{{avatar.status}}'})
Inside the mixin you can now access e.g. #{avatar.uuid}
I considder to automate this further, because this leads to a duplication of the models code which is not so nice yet. I will share my solution if I get one :)
I figured out that mixins cannot be used in Angular as the scope is to be defined. Hence now created element directive and passed in the template (which was meant to be written in Mixin) as the templateUrl in it.

backbone with requirejs : View and subviews and r.js

I have a view that requires requires Backbone, Undescore, jquery etc.
example
define(['jquery','undescore','backbone','subviewA', 'subviewB'], function($,_,Backbone, SubviewA, SubviewB){
var View = Backbone.View.extend({
//other methods here
render : function() {
this.subviewA = new SubviewA();
this.subviewA.render();
this.subviewB = new SubviewB();
this.subviewB.render();
return this;
}
});
});
subview example
define(['jquery','undescore','backbone','text!templates/subviewA'], function($,_,Backbone, template){
var SubviewA = Backbone.View.extend({
//other methods here
render : function() {
this.$el.html(template);
return this;
}
});
});
My question is if I need to include jquery, undescore and backbone in the subviews too ir I can omit them?
EDIT
I am asking cause in r.js I need every time to tell it to not to biuld those dependencies inside each module.
Theoretically, if you don't use the $ or _ symbols in your views, you don't need to list jquery and underscore as direct dependencies of your module (whether it is a view or a subview doesn't change that).
You do need to include backbone though, since you reference it directly with : Backbone.View. If you want to be absolutely sure that the Backbone symbol is defined you should declare it as a dependency.
Some libs register themselves both as AMD modules and as global variables (typically jquery does that). Backbone doesn't support AMD directly and registers itself at the global level regardless of how it is used. In theory you could not declare it as a dependency, but then you have the risk that require will try and load the script before backbone is loaded in which case the Backbone symbol will not be defined.
It doesn't matter much if you redondantly declare the dependencies except for the additional caracters, thus the additional script size.
You can omit any requirements which aren't used.
In your examples (ignoring omitted code!), you can remove jquery and undescore (sic) but not backbone (since you use it via Backbone.View.extend).
Obviously you need to keep your requirement names and variables in sync.

backbone selector and using find

I am seeing some strange behavior that I'm hoping someone can explain.
From the render method in a backbone view I have been attempting to do the following:
this.$(".msg").colorbox();
And
this.$el.find(".msg").colorbox();
However in both cases, although the msg elements are located, when trying to invoke the colorbox method on the returned elements I get an exception that the method is not defined.
However when I use:
$(this.el).find(".msg").colorbox();
All is well. Is anyone aware of why this might be?
It is a common issue. Surely colorbox is a jQuery plugin. The jQuery plugin is injected until the View's Element is added to the DOM of your Page.
I mean, your code is normal to fail with the natural behavior.
$('body').append( view.render().el );
But if you do this, it will works:
$('body').append( view.el );
view.render();
Third party Backbone.js Plugins has a method "named" onRender that is executed after render the View(and assuming that added to the DOM). But if you do not work with additional Backbone.js Plugins just be sure to call the colorbox until your View was added to the DOM.
Shooting in the dark...
this.$el and $(this.el) are differente instances even if both make reference to the same DOM element.
Maybe since the moment Backbone did precompile this.$el = $(this.el) to the moment you call this.$el.colorbox() something has happend so this function is not available and it has never been available in the instance this.$el.
I don't know what is colorbox() but if this is part of a third part jQuery plugin can be important the order in that your JS code is loaded?

Resources