Rendering custom views

In this section, we will look at the rendering process for SproutCore views. Updating the DOM is one of the slowest points in a web application and so, there are some very important steps that SproutCore uses to avoid touching the DOM unnecessarily. While all of the pre-built SproutCore views are already written to take full advantage of this, when we do custom rendering, it's important that we understand the render cycle in order to keep our views fast. Don't worry; it's not difficult to follow and you will have no problem creating complex views by the time we're done with this chapter.

We've already discussed how to affect the view's top level element by setting layerId, tagName, classNames, and layout but we haven't yet discussed how to create custom inner content for the element. To do so, there are two methods in SC.View that we use: render and update. The render method is called the first time the view is displayed and update is called each time the view's display changes.

Let's look at the render method first. Its job is to generate the HTML string to be passed to the Display layer and it does this using a simple HTML string builder called SC.RenderContext. Let's start by creating a custom label view class, NameLabelView, for our fictional application, MyApp:

In my_app/views/name_label_view.js:

MyApp.NameLabelView = SC.View.extend({

  /** The name. */
 name: '',

  /** @private Generates the view element's content.

    @param SC.RenderContext context the string builder object.
  */
  render: function (context) {
    var name = this.get('name'),

    // Add a "Name:" label along with the name.
    context.push('<label class="name-label">Name: </label><span>' + name + '</span>'), 
  }
});

As you can see, to render this view, all we do is push a Name: label term followed by the current value of name into the render context we are given. The push method simply adds the given string to the context, unaltered.

While you can use push a lot of the time, the render context does have more declarative methods that we can use to build the output. Here is the same render method using a series of build commands:

render: function (context) {
  var name = this.get('name'),

  // Add a "Name:" label.
  context = context.begin('label')
    .addClass('name-label')
    .push("Name: ")
    .end();

  // Add the name.
  context = context.begin('span').push(name).end();
}

This time we used begin('label') to start a new sub-context specific to the label element. We set its class using addClass, pushed the Name: string to it, and closed it off before starting another sub-context for span.

Tip

Along with addClass, the other methods you will find useful are setClass, addStyle, setStyle, addAttr, and setAttr. You can find more information on each of these in the documentation of SC.RenderContext.

Now, whenever an instance of MyApp.NameLabelView is appended to the document, its render function will be called and our custom label will appear in the DOM.

Note

In order to update DOM most efficiently, when a pane is appended, SproutCore will call the render function for every child view recursively, in order to build the entire HTML string at once. The final string will then be inserted into the DOM in a single call, which is significantly faster than building one child view at a time within the DOM.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.17.137