- Details
- Written by: Stanko Milosev
- Category: Knockout
- Hits: 2508
/*global google, ko*/
/*jshint esversion: 6 */
/* jshint -W031 */
(function (ns){
"use strict";
var mapOptions,
mapCanvas,
map,
gpsViewModel;
mapOptions = {
zoom: 6,
center: { lat: -34.397, lng: 150.644},
mapTypeId: google.maps.MapTypeId.ROADMAP
};
mapCanvas = document.getElementById('map-canvas');
if (!map) {
map = new google.maps.Map(mapCanvas, mapOptions);
gpsViewModel = new ns.GpsViewModel();
ko.applyBindings(gpsViewModel);
google.maps.event.addListener(map, 'click', function (evemt) {
new google.maps.Circle({
strokeColor: "#FF0000",
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: "#FF0000",
fillOpacity: 0.35,
map,
center: { lat: gpsViewModel.lat(), lng: gpsViewModel.lng()},
radius: Math.sqrt(603502) * 100
});
});
google.maps.event.addListener(map, 'mousemove', function (event) {
gpsViewModel.lat(event.latLng.lat());
gpsViewModel.lng(event.latLng.lng());
});
}
}(window.milosev));
gps.js:
/*global window, ko*/
(function (ns) {
"use strict";
var self;
ns.GpsViewModel = function () {
self = this;
self.lat = ko.observable();
self.lng = ko.observable();
return {
lat: self.lat,
lng: self.lng
};
};
}(window.milosev));
Notice line:
radius: Math.sqrt(603502) * 100
That was just copy / paste, otherwise radius is in meters Source download from here. Live example:
Langitude:
Longitude:
- Details
- Written by: Stanko Milosev
- Category: Knockout
- Hits: 2468
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="js/index.js"></script>
<script type="text/javascript" src="js/lib/knockout-3.5.1.js"></script>
<script type="text/javascript" src="js/lib/jquery-3.4.1.min.js"></script>
</head>
<body onload="DoApply()">
Cities:
<span data-bind="template: {name: 'cities-template', foreach: cities}"></span>
<script type="text/html" id="cities-template" >
<br/>
<input data-bind="id: id, name: name" type="checkbox">
<label data-bind="for: name, text: name"></label>
</script>
</body>
</html>
JS:
function MyViewModel() {
var self = this;
self.cities = ko.observableArray([]);
$.getJSON("cities.json", function(data) {
data.forEach(function (item, index) {
self.cities.push({name: item.Name, id:item.ID});
});
})
}
function DoApply() {
ko.applyBindings(new MyViewModel());
}
Where cities.json looks like:
[
{
"ID": 0,
"Name": "Bonn"
},
{
"ID": 0,
"Name": "Petrovaradin"
},
{
"ID": 0,
"Name": "Novi Sad"
},
{
"ID": 0,
"Name": "Balingen"
}
]
Live example see here.
---
Edit: observableArray must be global, something like ns.cities = ko.observableArray([]);, and pushed should be observable:
/*global window, ko*/
(function (ns) {
"use strict";
ns.CitiesViewModel = function () {
var self = this,
getCities = new GetCities(),
city = ko.observable();
ns.cities = ko.observableArray();
function GetCities() {
$.getJSON("api/cities", function (data) {
data.forEach(function (item, index) {
city({ name: item.Name, id: item.ID });
ns.cities.push(city());
});
});
}
return {
myCities: getCities
}
}
}(window.milosev));
---
Or even better and make it part of CitiesViewModel:
/*global window, ko, $*/
(function (ns) {
"use strict";
ns.CitiesViewModel = function () {
var self = this,
getCities = new GetCities(),
city = ko.observable();
function GetCities() {
self.cities = ko.observableArray();
$.getJSON("api/cities", function (data) {
data.forEach(function (item, index) {
city({ name: item.Name, id: item.ID });
self.cities.push(city());
});
});
return self.cities;
}
return {
cities: getCities
};
};
}(window.milosev));
- Details
- Written by: Stanko Milosev
- Category: Knockout
- Hits: 4215
Example which I am using when I want to see which model I am sending to knockout.
HTML:
<body>
<div data-bind="text: function() {debugger; return myText}()"></div>
</body>
JS:
/*global ko*/
(function () {
"use strict";
function MyModel() {
var self = this;
self.myText = ko.observable("Test");
}
MyModel = new MyModel();
ko.applyBindings(MyModel);
}());
Notice in HTML line:
<div data-bind="text: function() {debugger; return myText}()"></div>
In that line you can see debugger, and also return, which will force function to return value. Now you can debug knockout.
- Details
- Written by: Stanko Milosev
- Category: Knockout
- Hits: 4456
In custom bindings you can pass whole object, parse it and later use it, also you can pass a function (like observable for example).
HTML
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<script type="text/javascript" src="/knockout-3.3.0.js"></script>
<script type="text/javascript" src="/index.ko.extension.js" defer></script>
<script type="text/javascript" src="/index.js" defer></script>
</head>
<body>
<div data-bind="myBind: {propertyOne: testOne, propertyTwo: testTwo}"></div>
</body>
</html>
Here notice part:
<div data-bind="myBind: {propertyOne: testOne, propertyTwo: testTwo}"></div>
Now index.js:
/*global window, ko*/
function MyLog(msg) {
function doTheLog(msg) {
console.log(msg);
}
return {
doTheLog: doTheLog
}
};
window.doSomething = new MyLog();
window.testOne = "test one";
window.testTwo = "test two";
ko.applyBindings();
Here notice that I have created global variables testOne and testTwo, I need them for binding.
index.ko.extension.js:
/*global ko, console*/
/*jslint unparam: true*/
ko.bindingHandlers.myBind = {
init: function (element, valueAccessor) {
"use strict";
var myObjExample = ko.unwrap(valueAccessor());
doSomething.doTheLog(myObjExample.propertyOne);
doSomething.doTheLog(myObjExample.propertyTwo);
}
};
/*jslint unparam: false*/
Here notice:
var myObjExample = ko.unwrap(valueAccessor());
With that I am actually parsing my object.
Unit test looks like this:
/*global describe, it, expect, beforeEach, ko, window, document, $*/
describe("my bind", function () {
"use strict";
var sut;
beforeEach(function () {
//'<div data-bind="myBind: {propertyOne: testOne, propertyTwo: testTwo}"></div>'
var myDiv = document.createElement('div');
myDiv.setAttribute("data-bind", "myBind: {propertyOne: testOne, propertyTwo: testTwo}");
document.body.appendChild(myDiv);
window.testOne = "test one";
window.testTwo = "test two";
window.doSomething = jasmine.createSpyObj('MyLog', ['doTheLog']);
ko.applyBindings();
});
it("gets object from value acessor", function () {
expect(window.doSomething.doTheLog).toHaveBeenCalled();
});
});
Example download from here.
---
Actually, better unit test looks like:
/*global describe, it, expect, beforeEach, ko, window, document*/
describe("my bind", function () {
"use strict";
var sut,
testOne,
testTwo;
beforeEach(function () {
var myDiv = document.createElement('div');
testOne = jasmine.createSpy("testOne");
testTwo = jasmine.createSpy("testTwo");
myDiv.setAttribute("data-bind", "myBind: {testOne: testOne, testTwo: testTwo}");
document.body.appendChild(myDiv);
window.doSomething = jasmine.createSpyObj('MyLog', ['doTheLog']);
ko.applyBindings({testOne: testOne, testTwo: testTwo});
});
it("gets object from value acessor", function () {
expect(window.doSomething.doTheLog).toHaveBeenCalled();
});
});
Notice first my binding:
myDiv.setAttribute("data-bind", "myBind: {testOne: testOne, testTwo: testTwo}");
Then the apply bindings:
ko.applyBindings({testOne: testOne, testTwo: testTwo});
Version with this test download from here.