Skip to content

Instantly share code, notes, and snippets.

@kesne
Created January 11, 2014 05:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kesne/8367335 to your computer and use it in GitHub Desktop.
Save kesne/8367335 to your computer and use it in GitHub Desktop.
Fact.JS Demo
//Create app view:
fact.view('app', {
//called on render of the view:
render: function(elem){
//Set up the fact.js router with the app view. We could make this call anywhere, such as after the render, but it's easy here because we have reference to the just-created element (elem).
fact.router({
//The element that we want the router to apply to. In this case, it's the outlet
element: elem.$('.outlet'),
//Routes that we specify:
routes: {
//Comma-separated routes, if you want them:
'/, /home': 'home',
//The key is the route that you want matched, and the value is the view that you want rendered.
'/about, /info': 'about',
'/contact': 'contact'
},
//The base route which is called if none of the above routes are matched. Could be a 404 page if you want.
base: '/'
});
}
});
/*
* VIEWS:
*/
//Create our home view:
fact.view('home', {
//The ID of the template that you want.
template: 'home',
//You can also use URLs, like below:
//templateUrl: 'templates/home.html'
//The controller that you want to associate with the view. By having all of these separate, it makes everything highly decoupled, interchangable, and flexible.
//Eventually, I have the idea of making this all into a "factoid", that contains the view/model/controller all in one go, but for now, it's decoupled.
controller: 'HomeController'
});
//Create our about view:
fact.view('home', {
//The ID of the template that you want.
template: 'about'
//We don't need a controller for this view, so we just won't specify one.
});
//Contact view
fact.view('contact', {
template: 'contact',
controller: 'ContactController'
});
/*
* CONTROLLERS:
*/
fact.controller('HomeController', {
properties: {
person: 'World'
},
methods: {
titleChanged: function(from, to){
//This method gets called when the title property changes. This can happen either in the view, with a value binding, or explicity with a set function.
console.log('Value changed from ' + from + ' to ' + to);
}
},
render: function(){
//Set the person property:
this.set('person', 'Diego');
//This should cause titleChanged to be called on render!
//Note that the view bound to this controller will automatically update.
}
});
fact.controller('ContactController', {
//The "model":
properties: {
name: 'Your name here...'
},
methods: {
sendMail: function(){
//Get the name property. We use get/set functions because auto-binding is weird.
var name = this.get('name');
//Reset the name property. This will update the view:
this.set('name', '');
//Do something with name...
}
},
render: function(elem){
//This makes it highly encapsulated, because elem.$ only runs the selector in the element itself, acting like elem.find, so you can reuse this view/controller.
elem.$('.sendMailButton').click(function(){
console.log();
});
//Note: use a live listener on the element so it survives any dom manipulations.
}
});
//Render the app. If no element is specified, then we render into the document.body.
fact.render('app');
<!doctype html>
<html>
<head>
<title>Fact.JS Demo</title>
</head>
<body>
<script type="text/fact" id="app">
<!-- Create a sample navbar to move through the application -->
<div class="navbar">
<!-- The router helper makes it easy to link to a specified route -->
<a href="{{router '/home'}}">Home</a>
<a href="{{router '/about'}}">About</a>
<a href="{{router '/contact'}}">Contact</a>
</div>
<!-- Content from the router will print here: -->
<div class="outlet"></div>
</script>
<script type="text/fact" id="home">
Hello, {{person}}!
</script>
<script type="text/fact" id="about">
This is the about page.
</script>
<script type="text/fact" id="contact">
Get in touch with us! Tell us your name!
<input type="text" {{bind-value 'name'}} placeholder="Your name..." />
Entered Name: {{name}}
<!-- Bind the click event: -->
<button {{bind-click 'sendMail'}}>Send Mail!</button>
<!-- Bind any event: -->
<button {{bind-event 'click' 'sendMail'}}>Send Mail With Explicit Binding</button>
<!-- Bound via the controller! -->
<button class="sendMailButton">Send Mail With Explicit Binding</button>
</script>
<!-- Load app.js -->
<script src="app.js"></script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment