简体   繁体   中英

Backbone.js View Tagname set dynamically?

I'm trying to set up the base architecture for a Phonegap project using jQueryMobile and Backbone.js
We will be targeting multiple platforms and plan on expanding in the future.
I want my Backbone code to be completely ignorant of the types of HTML elements associated with the Views since we have no idea what the views will look like across the platforms.
A simple example would be that on one platform a List of items might be made from a UL and LI elements, but on another for some reason we might want to switch it to a DIV and P elements.

At the moment, if I don't specify a tagName, it defaults to a DIV .
I want to be able to provide a template like this on one page:

<script id="attachmentTemplate" type="text/template">
     <li><a href="#"><%= title %></a></li>
</script>

and on another provide:

<script id="attachmentTemplate" type="text/template">
    <p><a href="#"><%= title %></a></p>
</script>

I can't do that without specifying a tagName (as I said, it defaults to DIV ).

Does anyone have any advice or methods to do this? The key is that I don't want the Javascript to be aware of the type of HTML element, I want the HTML to define that.

You can specify a tagName property in your view with a function, so it will be dynamic.

...

tagName: function(){
    return this.model.get('tagName');
},

...

Checkout this fiddle http://jsfiddle.net/b7mR6/

Though I wouldn't recommend this architecture you can override your render method:

render: function() 
{
    // unbind all handlers since delegateEvents was called in the constructor
    this.undelegateEvents();
    // set this.el to the domElement from the templates
    this.el = this.template(this.model.toJSON()); // or however you get to your template
    // create the shorthand dom reference that setElement() creates
    this.$el = $(this.el);
    // re-delegate the events
    this.delegateEvents();
}

what that means is that you don't need to worry about your tagName as you defined it in your template.

edit: looking through the Backbone code, this is exactly what setElement does, so in theory you could try

render: function() 
{
    var tpl = this.template(this.model.toJSON());
    this.setElement(tpl, true);
    return this;
}

As usual, I search and search and find no answer, then I ask a question and figure it out on my own.

I discovered that if I make my Template like this:

<script id="attachmentTemplate" tagname="li" type="text/template">
    <a href="#"><%= title %></a>
</script>

Then in my js code, when instantiating my View I can do this:
var attachmentView = new AttachmentListItemView({ tagName: $('#attachmentTemplate').attr('tagname'), model: item });

And it works perfectly.
No idea if that will be valid HTML or cause any problems down the road though.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM