BorisMoore / jsviews

Interactive data-driven views, MVVM and MVP, built on top of JsRender templates
http://www.jsviews.com/#jsviews
MIT License
855 stars 130 forks source link

How to use outerHtml for selector markup in top-level linking #339

Closed Dissolubilis closed 8 years ago

Dissolubilis commented 8 years ago

As far I know , instead of registering templates you can use any selector of the element with desired markup and "data-link" attributes in top-level linking. I.e.

$('.target').link(true, model, {tmpl: '.anyElem'})

where '.anyElem' is

<div class="anyElem"> <span data-link="text" > Generated </span> </div>

But that approach gets span as template, not the parent div. I must define outerHtml as template myself when I want such behavior. You can see my jsFiddle for the extended example

Is there any convenient way or option to use outerHtml of selector for template instead of innerHtml?

BorisMoore commented 8 years ago

No, referencing a template by a jQuery selector will use the innerHTML of the first element of the jQuery matched set. That is the usual scenario where the selector is typically a script element and the contents can be one or more elements/text nodes.

Can't you achieve your scenario by having the server render the template block (even if it is a dup of the initial rendered content the user sees)? I would prefer not to add new APIs for this scenario if I can avoid it...

<script type="text" id="c">
   <a href="#" data-link="href{:href}">
      <span data-link="text"></span>
    </a>
</script>    
<div class="col1">
<div class="myTmpl">
  <h1 data-link="header">I am server header</h1>
  <div class="content" data-link="{for content tmpl='#c'}">
    <a href="#" data-link="href{:href}">
      <span data-link="text">I am server content 1</span>
    </a>

Another approach is to use a helper function to get outerHTML as template:

<div class="content" data-link="{for content tmpl=~getOuter('.content > a')}">
('#getNewContent').on('click', function(){
  $('.myTmpl').link(true, {header: 'I am client header', 
    content:[
      {text:"i am client content 1", href:"new"},
      {text:"i am client content 2", href:"new2"}
    ]
  },
  {
    getOuter: function(sel) { 
      return $(sel)[0].outerHTML; 
    }
  });
});
Dissolubilis commented 8 years ago

Thanks, I will stick with another approach which using the helper function, it it more elegant way than my one. The thing is I would like to avoid any duplication of content, because the markup is much more huge than one shown in my example, and there are some difficulties to maintain same markup for both element and template.

BorisMoore commented 8 years ago

Makes sense. I'll close this issue...