试图将ko.mapping与TypeScript和RequireJS结合起来理解。据我所知,我可以创建一个视图模型,将其绑定到一个视图,并通过视图模型将一个复杂的对象公开给我的视图。我没办法把这事办好。web上的大多数示例都希望展示如何获取web服务响应并直接绑定它。我正在寻找一个更基本的例子--我只想把一个未绑定的对象映射到屏幕上。我当然可以手动完成,但我认为这个工具正是为了这个目的而设计的.
我有两个需要:
我一直在使用一些示例代码作为概念的证明,这是我能想到的最基本的版本。这个想法是用一个按钮呈现一个视图。该按钮的文本应该加载"Hello!“,当单击时将更新为”再见.“。
我想我的视图模型需要两个物体..。
我的理解(这可能是错误的)是,映射将接受POJO并在绑定对象中自动创建POJO的可观察版本。视图绑定到绑定对象。在任何时候,例如单击按钮,我都可以增强POJO,并将其重新加载到绑定对象中,我的视图将相应更新。
我的视图模型是连接的,因为我可以设置断点,并看到他们被击中。由于绑定对象不可用,页面加载失败。如果我从ko.mapping更改为标准的可观测值,它的负载就会很好。
当我考虑ko.mapping的时候,我错过了什么?我的方法有缺陷吗?
基本POJO类
class DefaultModel {
public myField: string;
}
export = DefaultModel;
视图
<!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>
视图模型
/// <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配置
/// <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);
});
});
});
发布于 2014-09-25 08:50:32
A)在视图模型代码中,对ko.mapping.fromJS
的调用只需要前两个参数。因为它返回绑定模型,所以不需要传递绑定模型。它应该是:
this.boundModel = ko.mapping.fromJS(this.basicModelInstance, {});
B) viewModel.boundModel
不是一个函数,而是一个对象。所以在html中,绑定text: boundModel().myField
应该是text: boundModel.myField
。
C)您误解了绑定的工作方式。一旦您有了绑定模型,就不需要更新"POJO“,然后每次视图模型中的内容发生更改时都重新创建绑定模型。淘汰赛提供的双向数据绑定将使您的视图模型和ui (html)保持同步,因此从那时起您只需要使用视图模型。当您需要使用视图模型中的内容并更新您的"POJO“(仅当您需要更新服务器时)时,您可以使用与ko.mapping.toJS
函数相反的ko.mapping.fromJS
函数。传入绑定模型,它将返回普通的JS "POJO“对象,删除所有可观察到的对象。
发布于 2014-09-25 16:18:21
我把这个授予了@wired_in,因为它提供了帮助。在这里,我将提供最终解决我的问题的代码的工作版本。
我的理论--如果映射可以获取AJAX调用的结果,并自动将其映射到可观察的位置,为什么任何普通的POJO都不能呢?嗯,可以的!这种基本的能力是解放的。现在,我可以自由地创建模型,而不会用“可观察”来污染它们。模型的行为可以像任何普通的对象,没有特殊的处理。操纵模型以满足需求,然后当需要在视图上表示时,通过ko.mapping.fromJS调用绑定它。
这是最后的解决办法。我会按照我提出的问题的顺序.
基本POJO类:
class DefaultModel {
public myField: string;
}
export = DefaultModel;
视图:
<!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>
视图模型:
/// <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: KnockoutObservable<DefaultModel>;
constructor() {
// 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);
}
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配置:
/// <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);
});
});
});
结论:
最后,我被困在三件事上.
现在我可以根据封面下的数据来控制我的观点何时会改变。无论数据是来自AJAX调用,还是来自第三方系统的内部计算操作,还是来自上传的文件--不管是什么--我现在可以在视图中看到数据。很酷。
最后,问题--“为什么在未绑定的POJO中有数据?为什么不使用绑定对象并将其作为可观察的对象来操作?”--我认为答案是“可移植性”。我想自由地传递一个普通的对象进出代码库,而不需要特别考虑。将对象标记为可观察对象的概念是框架强加的约束--使绑定成为可能的变通方法。要求在任何地方应用“可观察”属性是不可取的。分离关心宝贝!总之,从我的肥皂盒里.
谢谢@wired_in。
https://stackoverflow.com/questions/26043433
复制相似问题