Trying to understand ko.mapping in conjunction with TypeScript and RequireJS. As I understand it, I can create a view model, bind it to a view and expose a complex object to my view via the view model. I am having no luck getting this to work. Most examples on the web want to show how to take a web service response and bind it directly. I am seeking a more basic example than that - I just want to map an unbound object to the screen. I could certainly do it manually, but I think the tool was designed for this exact purpose...
I have two needs:
- show a value on initial display - possibly blank
- Use a button to change the value.
I have been playing with some sample code as a proof of concept, as the most basic version I could come up with. The idea is to present a view with a button. The text of the button should load with "Hello World!", and when clicked be updated to "Goodbye moon...".
I think my view model needs two objects...
- POJO
- binding object, instantiated to be a ko.mapping.fromJS({})
My understanding (which is likely wrong) is that the mapping will take the POJO in and automatically create an observable version of the POJO in the binding object. The view is bound to the binding object. At any time, such as a click of a button, I can augment my POJO, and reload into the binding object and my view will update accordingly.
My View Model is connected as I can set break points and watch them get hit. The loading of the page fails because the bound object is not available. If I change from ko.mapping to standard observables it loads fine.
What am I missing when considering ko.mapping? Is my approach completely flawed?
Basic POJO Class
class DefaultModel {
public myField: string;
}
export = DefaultModel;
View
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>TypeScript HTML App</title>
<script data-main="Application/require-config" src="Scripts/require.js"></script>
</head>
<body>
<h1>TypeScript HTML App</h1>
<button id="myMethodTest" data-bind="text: boundModel().myField, click: function () { myButton_Click() }" ></button>
</body>
</html>
View Model
/// <reference path="../Scripts/typings/knockout/knockout.d.ts" />
/// <reference path="../Scripts/typings/knockout.mapping/knockout.mapping.d.ts" />
import DefaultModel = require("Models/DefaultModel");
import ko = require("knockout");
class DefaultViewModel {
public basicModelInstance: DefaultModel;
public boundModel: any;
constructor() {
// INSTANTIATE THE BOUND MODEL TO BE A BLANK KO MAPPED AWARE OBJECT
this.boundModel = ko.mapping.fromJS({});
// SETUP A BASIC INSTANCE OF A POJO
this.basicModelInstance = new DefaultModel;
this.basicModelInstance.myField = "Hello World!";
// LOAD THE POPULATED POJO INTO THE BOUND OBVSERVABLE OBJECT
this.boundModel = ko.mapping.fromJS(this.basicModelInstance, {}, this.boundModel);
}
myButton_Click() {
// UPDATE THE POJO
this.basicModelInstance.myField = "Goodbye Moon...";
// RELOAD THE POJO INTO THE BOUND OBJECT
this.boundModel = ko.mapping.fromJS(this.basicModelInstance, {}, this.boundModel);
}
}
export = DefaultViewModel;
RequireJS Configuration
/// <reference path="../Scripts/typings/requirejs/require.d.ts" />
require.config({
baseUrl: "",
paths: {
"jQuery": "Scripts/jquery-2.1.1",
"knockout": "Scripts/knockout-3.2.0.debug",
"utilities": "Application/utilities",
"ViewModelMapper": "Application/ViewModelMapper",
"komapping": "Scripts/knockout.mapping-latest.debug"
},
shim: {
"jQuery": {
exports: "$"
},
komapping: {
deps: ['knockout'],
exports: 'komapping'
}
},
});
require(["jQuery"], function ($) {
$(document).ready(function () {
// alert('dom ready');
require(["utilities", "knockout", "ViewModelMapper", "komapping"], (utilities, knockout, viewModelMapper, komapping) => {
utilities.defineExtensionMethods($);
knockout.mapping = komapping;
var url = window.location;
var location = utilities.getLocation(url);
var urlPath = location.pathname;
var urlPathWithoutExtension = urlPath.replace(".html", "");
var viewModel = viewModelMapper.getViewModel(urlPathWithoutExtension);
knockout.applyBindings(viewModel);
});
});
});