Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sammy.js and Knockout.js => Templating without templates?

I am fairly new to the concept of javascript client side development. I am running into an issue, though it may be I just don't understand how to accomplish something with the mash of frameworks.

I know I want to use Knockout for it's rich client side goodies. I also wanna use Sammy.js to allow for routing and passing data to the knockout views (I come from an MVC background where I stuff a model with data, then return view(model), and MVC binds it nice and good for me).

So now I am trying to do something similar client side...

Here is my Index.html :

<!DOCTYPE html>

<html>
  <head>
    <meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, maximum-scale=1.0, user-scalable=no;" />
    <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>

    <title>The EClassifieds Mobile</title>



      <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.js"></script>
      <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.min.js"></script>
<!--      <script type="text/javascript" src="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.js"></script>-->
      <script type="text/javascript" charset="utf-8" src="./scripts/cordova-1.8.1.js"></script>
      <script type="text/javascript" charset="utf-8" src="./scripts/knockout.js"></script>
      <script type="text/javascript" charset="utf-8" src="./scripts/templ.js"></script>
      <script type="text/javascript" charset="utf-8" src="./scripts/sammy.js"></script>      
      <script type="text/javascript" charset="utf-8" src="./scripts/sammy.tmpl.js"></script>
      <script type="text/javascript" charset="utf-8" src="./services/RouteManager.js"></script>
      <script type="text/javascript" charset="utf-8" src="./services/ApplicationManager.js"></script>


       <link rel="stylesheet" href="./style/site.css" type="text/css" media="screen" title="no title" charset="utf-8"/>       
 <!--      <link rel="stylesheet" href="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.css" />-->

  </head>
  <body>

  <div id="main">
  <h1>HELLO WORLD!</h1>
    <!--Sammy should update the content of this div dynamically, creating a SPA (single page application)-->
  </div>

  </body>
</html>

Here is my Sammy Configuration.

(function ($) {

    alert('Building Routes');
    var app = $.sammy('#main', function () {
        this.use('Tmpl', 'html'); 
        this.get('#/', function (context) {
            alert('Rendering Partial for Login page');
            context.app.swap('Loading...');
            this.render("/views/Login.html");
        });

    });

    $(function () {
        app.run('#/');
    });

})(jQuery);

Here is my Login.html

 <!--Model File Goes Here -->
    <script type="text/javascript" charset="utf-8" src="../models/Login.js"></script>

     <fieldset title="Please Login to Begin :">

            <div data-role="content" style="padding: 15px">
                <div data-role="fieldcontain">
                    <fieldset data-role="controlgroup" data-mini="true">
                        <label for="txtUsername">
                            Username
                        </label>
                        <input id="txtUsername" data-bind="value: username" placeholder="Stevie" value="" type="text" />
                    </fieldset>
                </div>
                <div data-role="fieldcontain">
                    <fieldset data-role="controlgroup" data-mini="true">
                        <label for="txtPassword">
                            Password
                        </label>
                        <input id="txtPassword" data-bind="value: password" placeholder="yep!" value="" type="password" />
                    </fieldset>
                </div>
                <a id="btnLogin" data-role="button" data-transition="fade" href="#page1" >
                    Login
                </a>
            </div>

            <div id="errorText">
                <h1></h1>            
            </div>

          <p id="deviceProperties">Loading device properties...</p>

    </fieldset>

 <script type="text/javascript">
      $(document).ready(function () {
              ko.applyBindings(new LoginDataModel(0, "Stevie", "theTV", true));

          });

</script>

I also need some way to pass the data from the sammy get handler, to the knockout page. Is there a way to do this, or am I attempting the impossible?


UPDATE 1 : I would really love to be able to do something like :

  var app = $.sammy('#main', function () {
            this.use('Tmpl', 'html'); 
            this.get('#/', function (context) {
                alert('Rendering Partial for Login page');
                context.app.swap('Loading...');
                var data = getLoginData();
                this.render("/views/Login.html", data);
            });

Sammy does this same exact thing using other template frameworks, however, I don't see how I would bind the $data in the Knockout view to the data passed from Sammy.

like image 834
David C Avatar asked Jun 28 '12 18:06

David C


People also ask

How does Ko identify the template block that needs to be rendered?

Shorthand syntax: If you just supply a string value, KO will interpret this as the ID of a template to render. The data it supplies to the template will be your current model object.

How can you bind data to templates?

Bind properties in a component's template to properties in the component's JavaScript class. In the template, surround the property with curly braces, { property } . To compute a value for the property, use a JavaScript getter in the JavaScript class, get property (){} .

How do I use KnockoutJS in HTML?

It is very easy to use KnockoutJS. Simply refer the JavaScript file using <script> tag in HTML pages. A page as in the following image will be displayed. Click on download link and you will get the latest knockout.

Why do we use KnockoutJS?

Knockout is a JavaScript library that helps you to create rich, responsive display and editor user interfaces with a clean underlying data model.


2 Answers

Not sure if you saw this, but the webmail tutorial on the knockoutjs website uses sammy.js for routing:

http://learn.knockoutjs.com/#/?tutorial=webmail

Here's a link to the finished product (so you can view source if you don't want to follow the whole tutorial) http://learn.knockoutjs.com/WebmailExampleStandalone.html

like image 142
daedalus28 Avatar answered Sep 22 '22 23:09

daedalus28


the Knockout.js-External-Templates plugin will help you in achieving this behavior. A good starting point will be from here EDIT: The "starting point" link now goes to malware.

Even John Papa endorses it here

The above solution is useful only when you frequently reuse your templates. Use inline templating whenever possible. Inline templating – and using foreach binding, performs around 1/3 faster than applying template from a separate DOM element, the so-called named template binding. More info on this here

like image 39
7 revs Avatar answered Sep 20 '22 23:09

7 revs