smallseo.info

backbone

Give your JS App some Backbone with Models, Views, Collections, and Events Backbone.js

Ember.js or Backbone.js for Restful backend [closed]

I already know that ember.js is a more heavy weight approach in contrast to backbone.js. I read a lot of articles about both.

I am asking myself, which framework works easier as frontend for a rails rest backend. For backbone.js I saw different approaches to call a rest backend. For ember it seems that I have to include some more libraries like 'data' or 'resources'. Why are there two libraries for this?

So whats the better choice? There arent a lot of examples to connect the frontend with the backend too. Whats a good working example for a backend rest call to this:

URI: ../restapi/topics GET auth credentials: admin/secrect format: json


Source: (StackOverflow)

How do I trigger the success callback on a model.save()?

this.model.save({
  success: function(model, response){
    console.log('success');
  },
  error: function(){
    console.log('error');
  }
})

The model is correctly posted to the server which handles the save, but the success callback is not fired. Do I need to send something back from the server ?


Source: (StackOverflow)

Backbone.View "el" confusion

How should a view's el be handled? It has to be set, otherwise events don't fire (see here).

But should it be an element that is already on the page? In my app, I render a (jQuery Templates) template into a Fancybox. What should the el be in that case?


Source: (StackOverflow)

Backbone View: Inherit and extend events from parent

Backbone's documentation states:

The events property may also be defined as a function that returns an events hash, to make it easier to programmatically define your events, as well as inherit them from parent views.

How do you inherit a parent's view events and extend them?

Parent View

var ParentView = Backbone.View.extend({
   events: {
      'click': 'onclick'
   }
});

Child View

var ChildView = ParentView.extend({
   events: function(){
      ????
   }
});

Source: (StackOverflow)

backbone.js - events, knowing what was clicked

In one of my backbone.js view classes, I have something like:

...

events: {
  'click ul#perpage span' : 'perpage'
},

perpage: function() {
  // Access the text of the span that was clicked here
  // Something like: alert($(element).text())
},

...

because my per page markup might have something like:

<ul id="perpage">
  <li><span>5</span></li>
  <li><span>10</span></li>
</ul>

So how exactly can I find information about the element that caused the event? Or in this instance, that was clicked?


Source: (StackOverflow)

Finding JavaScript memory leaks with Chrome

I've created a very simple test case that creates a Backbone view, attaches a handler to an event, and instantiates a user-defined class. I believe that by clicking the "Remove" button in this sample, everything will be cleaned up and there should be no memory leaks.

A jsfiddle for the code is here: http://jsfiddle.net/4QhR2/

// scope everything to a function
function main() {

    function MyWrapper() {
        this.element = null;
    }
    MyWrapper.prototype.set = function(elem) {
        this.element = elem;
    }
    MyWrapper.prototype.get = function() {
        return this.element;
    }

    var MyView = Backbone.View.extend({
        tagName : "div",
        id : "view",
        events : {
            "click #button" : "onButton",
        },    
        initialize : function(options) {        
            // done for demo purposes only, should be using templates
            this.html_text = "<input type='text' id='textbox' /><button id='button'>Remove</button>";        
            this.listenTo(this,"all",function(){console.log("Event: "+arguments[0]);});
        },
        render : function() {        
            this.$el.html(this.html_text);

            this.wrapper = new MyWrapper();
            this.wrapper.set(this.$("#textbox"));
            this.wrapper.get().val("placeholder");

            return this;
        },
        onButton : function() {
            // assume this gets .remove() called on subviews (if they existed)
            this.trigger("cleanup");
            this.remove();
        }
    });

    var view = new MyView();
    $("#content").append(view.render().el);
}

main();

However, I am unclear how to use Google Chrome's profiler to verify that this is, in fact, the case. There are a gazillion things that show up on the heap profiler snapshot, and I have no idea how to decode what's good/bad. The tutorials I've seen on it so far either just tell me to "use the snapshot profiler" or give me a hugely detailed manifesto on how the entire profiler works. Is it possible to just use the profiler as a tool, or do I really have to understand how the whole thing was engineered?

EDIT: Tutorials like these:

Gmail memory leak fixing

Using DevTools

Are representative of some of the stronger material out there, from what I've seen. However, beyond introducing the concept of the 3 Snapshot Technique, I find they offer very little in terms of practical knowledge (for a beginner like me). The 'Using DevTools' tutorial doesn't work through a real example, so its vague and general conceptual description of things aren't overly helpful. As for the 'Gmail' example:

So you found a leak. Now what?

  • Examine the retaining path of leaked objects in the lower half of the Profiles panel

  • If the allocation site cannot be easily inferred (i.e. event listeners):

  • Instrument the constructor of the retaining object via the JS console to save the stack trace for allocations

  • Using Closure? Enable the appropriate existing flag (i.e. goog.events.Listener.ENABLE_MONITORING) to set the creationStack property during construction

I find myself more confused after reading that, not less. And, again, it's just telling me to do things, not how to do them. From my perspective, all of the information out there is either too vague or would only make sense to someone who already understood the process.

Some of these more specific issues have been raised in @Jonathan Naguin's answer below.


Source: (StackOverflow)

Backbone.js: `extend` undefined?

Just getting started with Backbone.js. Simply including Backbone (either dev/production versions) causes the error:

Uncaught TypeError: Cannot call method 'extend' of undefined on Line 128:

// Attach all inheritable methods to the Model prototype. _.extend(Backbone.Model.prototype, Backbone.Events, {


Source: (StackOverflow)

Backbone.js: How to get the index of a model in a Backbone Collection?

Is there a way to find the index of a model within a collection?

Let's say in a view we have a model we're working on, could that model spit out it's index within the collection it's currently inside of? I'd like to do this because I want to access the model above or below the current target.

In other words is there something like:

index = this.model.index
modelAbove = this.collection.at( index-1 )

My data is a nested set so I can just do a search on the "lft" or "rgt" columns, but I didn't want to reinvent the wheel if Backbone already has this info available.


Source: (StackOverflow)

Backbone.js get and set nested object attribute

I have a simple question about Backbone.js' get and set functions.

1) With the code below, how can I 'get' or 'set' obj1.myAttribute1 directly?

Another question:

2) In the Model, aside from the defaults object, where can/should I declare my model's other attributes, such that they can be accessed via Backbone's get and set methods?

var MyModel = Backbone.Model.extend({
    defaults: {
        obj1 : {
            "myAttribute1" : false,
            "myAttribute2" : true,
        }
    }
})

var MyView = Backbone.View.extend({
    myFunc: function(){
        console.log(this.model.get("obj1"));
        //returns the obj1 object
        //but how do I get obj1.myAttribute1 directly so that it returns false?
    }
});

I know I can do:

this.model.get("obj1").myAttribute1;

but is that good practice?


Source: (StackOverflow)

External template in Underscore

I use Underscore template. It is possible to attach a external file as template?

In Backbone View I have:

 textTemplate: _.template( $('#practice-text-template').html() ),

 initialize: function(){                                            
  this.words = new WordList;            
  this.index = 0;
  this.render();
 },

In my html is:

<script id="practice-text-template" type="text/template">
   <h3>something code</h3>
</script>

It works well. But I need external template. I try:

<script id="practice-text-template" type="text/template" src="templates/tmp.js">

or

textTemplate: _.template( $('#practice-text-template').load('templates/tmp.js') ),

or

$('#practice-text-template').load('templates/tmp.js', function(data){ this.textTemplate = _.template( data ) })

but it did not work.

Thanks a lot for Your help. Tom


Source: (StackOverflow)

JavaScript I18n (internationalization) frameworks/libraries for client-side use? [closed]

We are currently creating a JavaScript application with backbone.js, and we need it translated or at least to support internationalization (I18n) in the future.

I've been looking around and found many libraries that help; Some are fairly simple where others seem overly complex. I found these in the past few hours:

Are there some blogs or sites that compare such frameworks? I would like to see if others already pointed out the pluses or pitfalls on any of these libraries.

We created our app module based on Require.js so if it has module support, that's definitely a plus.

Another requirement would be setting the locale after initialization, after we fetch the data from a webservice. We can't store static JSON files, except maybe for a default language, with the app. The translations come from a database and need to be sent to the app via a webservice, so we need to set the localization data dynamically instead of through JSON files. This is supported at least in Jed and i18next and jsperanto, but most likely also in others. In any case the app must never be blocked from execution.

I'm asking for help deciding which library suits best.


Something I noticed that is already missing in Jed, is providing a graceful alternative when a translation is not present in the locale dictionary. Jed just throws an error, something I find disturbing.

I prefer a cleaner way of handling missing translations, either provide a default string, print the key back to the screen. Additionally, but definitely not required, one could have the feature like i18next has, to post missing translations to a webservice. Though we won't need this, it is a nice feature.


Source: (StackOverflow)

Nested Models in Backbone.js, how to approach

I've got the following JSON provided from a server. With this, I want to create a model with a nested model. I am unsure of which is the way to achieve this.

//json
[{
    name : "example",
    layout : {
        x : 100,
        y : 100,
    }
}]

I want these to be converted to two nested backbone models with the following structure:

// structure
Image
    Layout
...

So I define the Layout model like so:

var Layout = Backbone.Model.extend({});

But which of the two (if any) techniques below should I use to define the Image model? A or B below?

A

var Image = Backbone.Model.extend({
    initialize: function() {
        this.set({ 'layout' : new Layout(this.get('layout')) })
    }
});

or, B

var Image = Backbone.Model.extend({
    initialize: function() {
        this.layout = new Layout( this.get('layout') );
    }
});

Source: (StackOverflow)

"Single-page" JS websites and SEO

There are a lot of cool tools for making powerful "single-page" JavaScript websites nowadays. In my opinion, this is done right by letting the server act as an API (and nothing more) and letting the client handle all of the HTML generation stuff. The problem with this "pattern" is the lack of search engine support. I can think of two solutions:

  1. When the user enters the website, let the server render the page exactly as the client would upon navigation. So if I go to http://example.com/my_path directly the server would render the same thing as the client would if I go to /my_path through pushState.
  2. Let the server provide a special website only for the search engine bots. If a normal user visits http://example.com/my_path the server should give him a JavaScript heavy version of the website. But if the Google bot visits, the server should give it some minimal HTML with the content I want Google to index.

The first solution is discussed further here. I have been working on a website doing this and it's not a very nice experience. It's not DRY and in my case I had to use two different template engines for the client and the server.

I think I have seen the second solution for some good ol' Flash websites. I like this approach much more than the first one and with the right tool on the server it could be done quite painlessly.

So what I'm really wondering is the following:

  • Can you think of any better solution?
  • What are the disadvantages with the second solution? If Google in some way finds out that I'm not serving the exact same content for the Google bot as a regular user, would I then be punished in the search results?

Source: (StackOverflow)

How to render and append sub-views in Backbone.js

I have a nested-View setup which can get somewhat deep in my application. There are a bunch of ways I could think of initializing, rendering and appending the sub-views, but I'm wondering what common practice is.

Here are a couple I've thought of:

initialize : function () {

    this.subView1 = new Subview({options});
    this.subView2 = new Subview({options});
},

render : function () {

    this.$el.html(this.template());

    this.subView1.setElement('.some-el').render();
    this.subView2.setElement('.some-el').render();
}

Pros: You don't have to worry about maintaining the right DOM order with appending. The views are initialized early on, so there isn't as much to do all at once in the render function.

Cons: You are forced to re-delegateEvents(), which might be costly? The parent view's render function is cluttered with all of the subview rendering that needs to happen? You don't have the ability to set the tagName of the elements, so the template needs to maintain the correct tagNames.

Another way:

initialize : function () {

},

render : function () {

    this.$el.empty();

    this.subView1 = new Subview({options});
    this.subView2 = new Subview({options});

    this.$el.append(this.subView1.render().el, this.subView2.render().el);
}

Pros: You don't have to re-delegate events. You don't need a template that just contains empty placeholders and your tagName's are back to being defined by the view.

Cons: You now have to make sure to append things in the right order. The parent view's render is still cluttered by the subview rendering.

With an onRender event:

initialize : function () {
    this.on('render', this.onRender);
    this.subView1 = new Subview({options});
    this.subView2 = new Subview({options});
},

render : function () {

    this.$el.html(this.template);

    //other stuff

    return this.trigger('render');
},

onRender : function () {

    this.subView1.setElement('.some-el').render();
    this.subView2.setElement('.some-el').render();
}

Pros: The subview logic is now separated from the view's render() method.

With an onRender event:

initialize : function () {
    this.on('render', this.onRender);
},

render : function () {

    this.$el.html(this.template);

    //other stuff

    return this.trigger('render');
},

onRender : function () {
    this.subView1 = new Subview();
    this.subView2 = new Subview();
    this.subView1.setElement('.some-el').render();
    this.subView2.setElement('.some-el').render();
}

I've kind of mix and matched a bunch of different practices across all of these examples (so sorry about that) but what are the ones that you would keep or add? and what would you not do?

Summary of practices:

  • Instantiate subviews in initialize or in render?
  • Perform all sub-view rendering logic in render or in onRender?
  • Use setElement or append/appendTo?

Source: (StackOverflow)

Loading Backbone and Underscore using RequireJS

I'm trying to load Backbone and Underscore (as well as jQuery) with RequireJS. With the latest versions of Backbone and Underscore, it seems kind of tricky. For one, Underscore automatically registers itself as a module, but Backbone assumes Underscore is available globally. I should also note that Backbone doesn't seem to register itself as a module which makes it kind of inconsistent with the other libs. This is the best main.js I could come up with that works:

require(
{
    paths: {
        'backbone': 'libs/backbone/backbone-require',
        'templates': '../templates'
    }
},
[
    // jQuery registers itself as a module.
    'http://cdnjs.cloudflare.com/ajax/libs/jquery/1.7/jquery.min.js',

    // Underscore registers itself as a module.
    'http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.2.1/underscore-min.js'
], function() {

    // These nested require() calls are just due to how Backbone is built.  Underscore basically says if require()
    // is available then it will automatically register an "underscore" module, but it won't register underscore
    // as a global "_".  However, Backbone expects Underscore to be a global variable.  To make this work, we require
    // the Underscore module after it's been defined from within Underscore and set it as a global variable for
    // Backbone's sake.  Hopefully Backbone will soon be able to use the Underscore module directly instead of
    // assuming it's global.
    require(['underscore'], function(_) {
        window._ = _;
    });

    require([
        'order!http://cdnjs.cloudflare.com/ajax/libs/backbone.js/0.5.3/backbone-min.js',
        'order!app'
    ], function(a, app) {
        app.initialize();
    })
});

I should mention that, while it works, the optimizer chokes on it. I receive the following:

Tracing dependencies for: main
js: "/home/httpd/aahardy/requirejs/r.js", line 7619: exception from uncaught JavaScript throw: Error: Error: Error evaluating module "undefined" at location "/home/httpd/aahardy/phoenix/trunk/ui/js/../../ui-build/js/underscore.js":
JavaException: java.io.FileNotFoundException: /home/httpd/aahardy/phoenix/trunk/ui/js/../../ui-build/js/underscore.js (No such file or directory)
fileName:/home/httpd/aahardy/phoenix/trunk/ui/js/../../ui-build/js/underscore.js
lineNumber: undefined
http://requirejs.org/docs/errors.html#defineerror
In module tree:
    main

Is there a better way of handling this? Thanks!


Source: (StackOverflow)