2

The goal

Pass to the DOM strings with HTML and render it.

The scenario

I'm extending properties of an observable (with KnockoutJS) using the follow syntax:

self.showDetails.subscribe(function (context) {
    var details = this.showDetails();
    details.nameWithCnpj = context.name() + " <small>" + context.cnpj() + "</small>";
}, this);

If you pay attention on the following line, you can see the HTML on it:

details.nameWithCnpj = context.name() + " <small>" + context.cnpj() + "</small>";

When the <small></small> tag arrives on the HTML, it is rendered as string instead of vanilla HTML.

The container that houses the nameWithCnpj (using KnockoutJS) is the following:

<h2 class="bold float-left" data-bind="text: nameWithCnpj"></h2>

So I ask: How can I teach to JavaScript (or HTML) that the nameWithCnpj variable should be a DOM element instead of a simple string?

10
  • It depends on how do you display the nameWithCnpj, please post the code where you display the content of nameWithCnpj ! Commented Aug 29, 2013 at 13:01
  • Sorry, @nemesv. Take a look on the main post now — I updated it. Commented Aug 29, 2013 at 13:03
  • 1
    Don't you think a binding would be more appropriate? You're taking a mvvm and closely coupling UI logic in the model. Commented Aug 29, 2013 at 13:05
  • @BradChristie Are you saying to me for use html binding instead of text? (Just for curiosity) Commented Aug 29, 2013 at 13:06
  • @GuilhermeOderdenge: I'm saying with a MVVM the minute you're placing html in the model you're doing it wrong. Commented Aug 29, 2013 at 13:07

1 Answer 1

5

You need to use the html binding instead of text:

The html binding causes the associated DOM element to display the HTML specified by your parameter.

Typically this is useful when values in your view model are actually strings of HTML markup that you want to render.

So change your view to:

<h2 class="bold float-left" data-bind="html: nameWithCnpj"></h2>

If you want to be more MVVM you can create a template which encapsulates your formatting logic and use the template binding:

<h2 class="bold float-left" 
    data-bind="template: { name: 'nameWithCnpj', data: showDetails}"></h2>

<script id="nameWithCnpj" type="text/html">
   <span data-bind="text: name"></span>
   <small data-bind="text: cpnj"></small>
</script>
Sign up to request clarification or add additional context in comments.

5 Comments

yes! that's why there are models & views. though I'd take it a step farther and get <small> the heck out of that property then create a nameWithCnpj binding all on its own.
@BradChristie yeah in general I agree, but the html binding exists for a good reason, sometimes you have some generated 3th party html what you need to display (like in CMS apps) so it is not bad to use but. In this concrete case if this is the only usage of this HTML fragment creating a one time only custom binding seems overkill for me...
@GuilhermeOderdenge I've extended my answer with a sample template usage.
nemesv AMAZING TEMPLATE USAGE! I believe it was my lack of creativity, haha. By the way, thank you so much for your and @BradChristie attention. Thank you, thank you & thank you guys!
Aw, no virtual elements? ;p gj nemesv

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.