<html>
<head>
<link href="https://code.jquery.com/qunit/qunit-git.css" rel="stylesheet" type="text/css" />
<meta name="description" content="CanJS Models">
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<div id="qunit"></div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.js"></script>
<script src="//canjs.com/release/latest/can.jquery.js"></script>
<script src="//canjs.com/release/latest/can.construct.super.js"></script>
<script src="//canjs.com/release/latest/can.map.define.js"></script>
<script src="//canjs.com/release/latest/can.stache.js"></script>
<script src="//canjs.com/release/latest/can.fixture.js"></script>
<script src="https://code.jquery.com/qunit/qunit-git.js"></script>
<script>
var stateStore = can.fixture.store([
{ name: 'California', short: 'CA' },
{ name: 'New York', short: 'NY'}
],{});
var cityStore = can.fixture.store([
{ state: 'CA', name: 'Pasadena' },
{ state: 'NY', name: 'Albany' }
],{});
can.fixture({
'GET /api/states': stateStore.findAll,
'GET /api/cities': cityStore.findAll,
'GET /api/restaurants': function(){
return [{
_id: 1,
name: 'Cheese City',
slug:'cheese-city',
address: {
city: 'Casadina',
state: 'CA'
}
}];
}
});
var State = can.Model.extend({
resource: "/api/states",
id: "short"
},{});
var City = can.Model.extend({
resource: "/api/cities",
id: "name"
},{});
var Restaurant = can.Model.extend({
resource: "/api/restaurants"
},{});
</script>
</body>
</html>
// State, City, and Restaurant models and
// fixtures created in the HTML tab
// Create a ViewModel that makes `cities` depend on the `state`
var RestaurantListVM = can.Map.extend({
define: {
// `states` initialized with a promise that resolves
// to a list of all states.
states: {
value: function() {
return State.findAll({});
}
},
// `state` and `city` are "source" state values, which all other
// values are derived from.
state: {
type: 'string',
set: function() {
// Remove the city when the state changes
this.attr('city', null);
}
},
city: {
type: 'string'
},
// `cities` depends on the value of `state`.
// If `state` is set, `cities` will be a promise that
// resolves to a list of all cities for that state.
cities: {
get: function() {
var state = this.attr('state');
if(!state) {
return null;
}
return City.findAll({ state });
}
},
// `restaurants` depends on the value of `state` and `city`.
// If both `state` and `city` are set, `restaurants` will
// return a promise that resolves to a list of all restaurants
// for that city and state.
restaurants: {
get: function() {
var state = this.attr('state'),
city = this.attr('city');
if(state && city) {
return Restaurant.findAll({
'address.state': state,
'address.city': city
});
}
return null;
}
}
}
});
// Test the ViewModel
QUnit.asyncTest("set state, then city, get restaurants", function(){
var vm = new RestaurantListVM();
// Set the state
vm.attr('state','CA');
// Make sure we get cities for it
vm.attr('cities').then(function(cities){
QUnit.ok(cities.length, "Got cities");
QUnit.ok(cities[0].attr("state"), "CA", "Got cities for the right state");
// Set the city
vm.attr("city","Pasadena");
// Make sure we get restaurants for it
vm.attr("restaurants").then(function(restaurants){
QUnit.ok(restaurants.length, "Got restaurants");
QUnit.start();
});
});
});
Output
300px
You can jump to the latest bin by adding /latest
to your URL
Keyboard Shortcuts
Shortcut | Action |
---|---|
ctrl + [num] | Toggle nth panel |
ctrl + 0 | Close focused panel |
ctrl + enter | Re-render output. If console visible: run JS in console |
Ctrl + l | Clear the console |
ctrl + / | Toggle comment on selected lines |
ctrl + ] | Indents selected lines |
ctrl + [ | Unindents selected lines |
tab | Code complete & Emmet expand |
ctrl + shift + L | Beautify code in active panel |
ctrl + s | Save & lock current Bin from further changes |
ctrl + shift + s | Open the share options |
ctrl + y | Archive Bin |
Complete list of JS Bin shortcuts |
JS Bin URLs
URL | Action |
---|---|
/ | Show the full rendered output. This content will update in real time as it's updated from the /edit url. |
/edit | Edit the current bin |
/watch | Follow a Code Casting session |
/embed | Create an embeddable version of the bin |
/latest | Load the very latest bin (/latest goes in place of the revision) |
/[username]/last | View the last edited bin for this user |
/[username]/last/edit | Edit the last edited bin for this user |
/[username]/last/watch | Follow the Code Casting session for the latest bin for this user |
/quiet | Remove analytics and edit button from rendered output |
.js | Load only the JavaScript for a bin |
.css | Load only the CSS for a bin |
Except for username prefixed urls, the url may start with http://jsbin.com/abc and the url fragments can be added to the url to view it differently. |