gpt4 book ai didi

javascript - 使用 TypeScript 和 RequireJS 的 knockout.mapping

转载 作者:搜寻专家 更新时间:2023-10-30 21:31:22 24 4
gpt4 key购买 nike

尝试结合 TypeScript 和 RequireJS 来理解 ko.mapping。据我了解,我可以创建一个 View 模型,将其绑定(bind)到 View 并通过 View 模型向我的 View 公开一个复杂的对象。我没有运气让这个工作。 Web 上的大多数示例都想展示如何获取 Web 服务响应并直接绑定(bind)它。我正在寻找一个比这更基本的例子——我只想将一个未绑定(bind)的对象映射到屏幕上。我当然可以手动完成,但我认为该工具正是为此目的而设计的...

我有两个需求:

  1. 在初始显示时显示一个值 - 可能为空白
  2. 使用按钮更改值。

我一直在玩一些示例代码作为概念证明,这是我能想到的最基本的版本。这个想法是用一个按钮来呈现一个 View 。按钮的文本应加载“Hello World!”,并在单击时更新为“再见月亮...”。

我认为我的 View 模型需要两个对象...

  1. POJO
  2. 绑定(bind)对象,实例化为 ko.mapping.fromJS({})

我的理解(这可能是错误的)是映射将接受 POJO 并自动在绑定(bind)对象中创建 POJO 的可观察版本。 View 绑定(bind)到绑定(bind)对象。在任何时候,例如单击一个按钮,我都可以扩充我的 POJO,并重新加载到绑定(bind)对象中,我的 View 将相应地更新。

我的 View 模型已连接,因为我可以设置断点并观察它们被击中。页面加载失败,因为绑定(bind)的对象不可用。如果我从 ko.mapping 更改为标准 observables,它加载正常。

考虑 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);
});
});
});

最佳答案

我将此奖励给@wired_in 提供的帮助。在这里,我将提供最终解决我的问题的代码的工作版本。

我的理论 - 如果映射可以获取 AJAX 调用的结果并自动神奇地将其映射到可观察对象,为什么普通的 POJO 不能?好吧,它可以!这种基本能力正在解放。现在我可以自由地创建模型,而不会用“可观察的”污染它们。这些模型可以像任何没有特殊处理的普通对象一样运行。根据需要操纵模型,然后在需要在 View 上表示时,通过 ko.mapping.fromJS 调用将其绑定(bind)。

这是最终的解决方案。我将按照提出原始问题的相同顺序提出它...


基本 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);
});
});
});

结论:

最后,我卡在了 3 件事上......

  1. 我的 View 错误地引用了 View 中的绑定(bind)对象模型。感谢@wired_in 在这方面的帮助
  2. 在构造函数中,我传递了太多参数。谢谢@wired_in 指出了这一点。的文档KnockoutJS.mapping 在这方面不清楚。我认为使用 1vs. 3 参数在这里是可选的。
  3. 在方法 myButton_Click 中,我需要传递对现有的,已经绑定(bind)的对象(A.K.A.,viewmodel inside a View 模型)。这是允许更新现有的关键绑定(bind)模型。

现在我可以根据幕后操作的数据来控制我的 View 何时更改。无论数据是来自 AJAX 调用,还是来自第三方系统的内部计算操作,来自上传的文件 - 不管怎样 - 我现在都可以在 View 中看到数据。很酷。

最后,问题 - “为什么在未绑定(bind)的 POJO 中有数据?为什么不直接使用绑定(bind)的对象并将其作为可观察对象进行操作?” - 我认为答案是“便携性”。我想要在没有特殊考虑的情况下自由地将普通对象传入和传出代码库。这种将对象标记为可观察的概念是框架强加的约束——一种使绑定(bind)成为可能的解决方法。要求在任何地方都应用“可观察”属性是不可取的。关注点分离宝贝!无论如何,现在离开我的肥皂盒......

感谢@wired_in。

关于javascript - 使用 TypeScript 和 RequireJS 的 knockout.mapping,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26043433/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com