Backbone-relational with Require.js (AMD) - backbone.js

I'm working on a fairly large web app in which I am going to be using require.js so I can compile it once it's ready for production, but I would like to use backbone-relational. I am also going to be using backbone-marionette, but I am not sure how it would be included in the define function of modules.
Does anyone have any experience with this?

I'm using Backbone Marionette with Relational and loading them with Require.js. The basic idea is that you need to ensure Relational is loaded. One way to do it is to include Relational as a requirement whenever you define a Relational model.
In my project, I created a simple script called bbloader.js (Backbone Loader) that loads all the relevant backbone models:
define([
'backbone',
'iosync',
'iobind',
'relational',
'marionette',
'marionette.async'
], function(Backbone) {
return Backbone;
});
And then throughout the project, I require bbloader instead of Backbone. For example:
define([
'jquery',
'underscore',
'bbloader',
// ...
], function($, _, Backbone) {
// ...
});
Backbone Relational is already AMD compatible, so you shouldn't need to do anything extra there.

Marionette 100% supports AMD. There's a few wiki pages on getting it up and running, and it's pretty simple:
https://github.com/derickbailey/backbone.marionette/wiki/Using-marionette-with-requirejs
I would assume BB-R works as well, but I don't use this plugin so I'm not 100% certain.

Related

ExtJs: basic questions

I'm currently learning ExtJs, but I can't seem to grasp my mind arround the following.
What is the difference between the array notation and the requires notation
For example:
view['MyPanel']
model['MyModel']
controller['MyController']
store['MyStore']
requires: ['namespace.view.MyPanel']
Do they do the same or ... ?
And why do I have to put ALL the views, models, controllers and stores used in the application inmediatley in the app.js?
Can someone clear those thing out to me? :)
Requires will just load the files matching the class name from the server. It will not instantiate anything. You should require what is needed in each view/controller/model, you don't need to have it all in app.js.
For instance, if you have a MyModel that has a relation to MySubModel, then MyModel would require MySubModel. Requires is essentially about loading other classes when needed so that they are fetched from the server before being used - since using a class when it is not loaded creates a noticable delay due to ExtJS having to fetch the class from the server before instantiating it.
The models, views and controllers arrays in a controller are a convinient way to require such resources as you don't have to specify the path to the models/controllers/views folders. See the docs on controller models config for example.
A guide on how to structure your application is available here even though I don't really like that they load all views and all controllers in this approach. But it's a good start. You can dynamically load stuff later on when your application grows.

How to split large AngularJS projects into modules

I come from the world of Backbone and JavascriptMVC. But I am really tempted to switch to AngularJS. So far, I have one big issue that keeps me from converting.
I create single page apps. Let's pretend it contains a tab module, a file upload module and a filelist module.
What I would do in Backbone is that I would split each of these as standalone modules
with their own view template, viewcontroller and so on. That way, I am able to use the module several places in my app. The modules don't know about anything other than itself.
How is this ment to be dealt with in AngularJS? Is it possible to create one angular.module per module (like for instance a tab module)?
I feel they tell a how to create many controllers within a module in their documentation. But that does not sound like what I need. Or am I misunderstanding some major concepts here?
EDIT:
I have done some more research. It looks like directives is what I am looking for. While a module in AngularJS represents the entire web app. So the mixing of the names 'components' and 'modules' is what confused me.
Am I on the correct path now?
You absolutely can define modules and you include your modules at the app level and then with dependency injection you allow your controllers to use what they need.
I have a proof of concept example for a small app I was working on to learn angular (it is pretty dirty and my playground):
http://plnkr.co/edit/1jGqaB00OznAUpyPZVT3
My app definition looks like this:
angular.module('myApp', ['ngResource','ui.bootstrap', 'myApp.services', 'myApp.servicesMovie', 'myApp.servicesSearch', 'myApp.servicesUtils', 'myApp.servicesMovieList'])
You can see I am including a bunch of different modules with my app and then an example of a controller that takes some services from the services module:
function SearchCtrl($scope, $rootScope, $route, $timeout, $routeParams, $location, SearchService, MovieListService) { etc }
Here is one of the module's defined (with its dependency too):
angular.module('myApp.servicesMovieList', ['myApp.services'])
With regards to templates, you can define these and include them with your route values:
$routeProvider.when('/view1', {templateUrl: 'view1.html', controller: ViewCtrl});
$routeProvider.when('/movie/:id', {templateUrl: 'movie-detail.html', controller: MovieCtrl, resolve: MovieCtrl.resolve});
$routeProvider.when('/search/:q/:p', {templateUrl: 'movie-search.html', controller: SearchCtrl});
$routeProvider.when('/searchlist/:url/:p', {templateUrl: 'movie-search.html', controller: SearchCtrl});
$routeProvider.otherwise({redirectTo: '/view1'});
}])
Or of course you can call them with ng-include
Yes, you're on the right path now. Another type of module in Angular are services. Services can be injected into any controller or directive (or even into other services) in a very clean manner.
Directives are primarily for reusable things that are visibly part of the UI, which is sort of reflected by the way they are put to use: by adding DOM elements/attributes.
Services are for more abstract things or things whose existence and behavior makes sense even without any directly corresponding user interface. The more logic you can sensibly shove into independent services, the more modular you application becomes and the more reusable the code is.
Controllers tend -- in my experience -- to be the least reusable and to be the first to grow complex and messy. (But that could just be me using them wrong.) The rule of thumb is to keep controllers as simple as humanly possible. Limit them to only pure business logic, and try to put most of that as well into services.
Angular does have a somewhat steep learning curve, but keep researching and then the different pieces will become apparent and fall into place. One resource right here on SO is this question: "Thinking in AngularJS" if I have a jQuery background?
Take a look at my post:
http://leog.me/log/large-angularjs-app-components
It's about a solution with RequireJS to partition the application in multiple modules that can be hooked together very easy.
Let me know if you find it helpful so I can put basic info here to avoid referring to a link instead of putting valuable content in the answer.

How do you structure your Backbone + RequireJS applications?

I've been struggling trying to strike the right balance between reusability and complexity when it comes to organizing my Backbone objects into AMD's (for medium- to large-scale applications)
(A) Should every Backbone object (models, views, etc) be in their own module?
(B) Should related Backbone objects be in the same AMD module? (ie: PersonModel, PersonCollection, PersonView objects in the same module definition)
Option (A) seems to allow the most flexibility and reusability, but also the most complexity because of the (potentially) high number of files. While option (B) may make it easier to manage things, but less flexible and really difficult to unit test.
How is (or has) everyone else structured these things?
I good thing about requirejs is that it allow you to abstract the physical files into structured namespaces. You can take the approach (A) and create each backbone class in their own file, then create a "namespace" module to glue all the related classes together.
// Suppose you have PersonView.js, PersonCollectionjs, PersonModel.js as modules
// create a Person module to function as namespace
define(["PersonModel", "PersonCollection", "PersonView"], function(model, collection, view) {
return {
Model: model,
Collection: collection,
View: view
};
});
This keep the modules organized in their own files and gives you some flexibility to write one module per class without requiring you to expose this organization for the rest of the application (I really don't like to have to write require("PersonView", "PersonModel" ... ) every time I need to use the person's objects, it's easier and cleaner for consumers to declare a dependency on a "namespace" instead of independent classes).
For medium to large backbone projects I prefer to use requirejs with a separate module for every model, collection, and view. I also use the "Text" plugin for requirejs so I can load underscore templates just as I would any other module. This for me seems to be the sanest way to manage a large project and I have never really felt overwhelmed with the number of files I have.
+1 on using the requirejs optimizer when pushing your app to production. Works really well.
http://requirejs.org/docs/optimization.html
I just released an open source toolkit which will hopefully help others as much as it helps me. It is a composition of many open source tools which gives you a working requirejs backbone app out of the box.
It provides single commands to run: dev web server, jasmine single browser test runner, jasmine js-test-driver multi browser test runner, and concatenization/minification for JavaScript and CSS. It also outputs an unminified version of your app for production debugging, precompiles your handlebar templates, and supports internationalization.
No setup is required. It just works.
http://github.com/davidjnelson...

Pattern for Backbone app using requirejs

I came across this article about about backbone apps with requirejs. There is one thing that seems really odd. Whenever they need a reference of Backbone, Underscore or jquery in my module I have to require them:
define([
'jQuery',
'Underscore',
'Backbone',
'collections/projects',
], function($, _, Backbone, ProjectsCollection, projectsListTemplate){
var projectListView = Backbone.View.extend({
el: $("#container"),
...
So is there really a need to go that way? Isn't a bit over engineered? Couldn't I just load Backbone and its dependencies before I start my app and use them as global objects like I would do it without requirejs? Or miss I something here?
There are pros/cons either way.
Advantage:
Your dependency management is completely controlled by require.js, instead of relying on synchronously-loaded globally-scoped libraries. It's elegant, modular, and is probably The Right Way to do things.
Advantage:
It's easier to swap in versions of libraries, particularly per-module. I've honestly never seen this in practice - it seems like a "what if" situation rather than something practical. If you do then you're probably hacking something together anyway, sacrificing the "code elegance" you're getting by using them as modules in the first place.
Disadvantage:
You get a lot of boilerplate imports.
define(['jQuery', 'underscore', 'backbone', 'raphael', ...],
In a large app, it could take a half dozen library dependencies before you get to your dependencies. In every module.
The redundancy feels especially unnecessary for Backbone-heavy apps, where each module is probably defining a Backbone model/controller/view - almost every module requires Backbone.
You could wrap them all into a single Lib module that you'd reference like Lib.$(...) or Lib._(...), but that's just moving the boilerplate out of the imports and into the code. It also negates advantage #2.
So which one?
I'd say to look at each library individually and decide whether or not it should be global or its own imported module.
If you're going to use the library almost everywhere (e.g. jQuery, Backbone), then just keep it global.
For other libraries you might only use them in a couple views (e.g. Raphael.js). In that case, import it as a module.

CakePHP and Plugins

I need to create plugins that hook into the functionality of my main application. CakePHP plugins only instantiate themselves when its own controller is called meaning I cannot affect the processes of my main application.
mainapp/action2baffected
myplugin/
I like the idea of having self contained pluggable models , is there any other way to get this to work? Creating models on the fly etc or write a plugin system from scratch with no cakeiness!
You can use components and behaviors (from the plugins) into your core application. There is one very good presentation of Pierre MARTIN Using reusing-plugins. It's a really inspirational resource.
We have put quite a lot of work into making plugins truly self contained in Infinitas
You can have a look at some of the methods that are used, but the main code is in the events. Everything from cache configs, db connections and include assets like css/js are done from within the plugin, even injecting some markup into views is handled.

Resources