我认为我的应用程序现在变得非常大,太大而无法使用单个ViewModel处理每个View.
所以我想知道创建多个ViewModel并将它们全部加载到一个View中会有多困难.需要注意的是,我还需要能够将X ViewModel数据传递到Y ViewModel数据中,以便各个ViewModel需要能够相互通信或至少相互了解.
例如,我有一个<select>下拉列表,选择下拉列表具有一个选定的状态,允许我在<select>另一个ViewModel 中将所选项目的ID传递给另一个Ajax调用....
在单个视图中处理众多ViewModel的任何要点赞赏:)
在我的视图模型中,我有一个IsMale值,其值为true或false.
在我的UI中,我希望将其绑定到以下单选按钮:
<label>Male
<input type="radio" name="IsMale" value="true" data-bind="checked:IsMale"/>
</label>
<label>Female
<input type="radio" name="IsMale" value="false" data-bind="checked:IsMale"/>
</label>
Run Code Online (Sandbox Code Playgroud)
我认为这个问题checked需要一个字符串"true"/"false".所以我的问题是,如何通过这个UI和模型获得这种双向绑定?
我还在学习Knockout的正确使用方法,并且我发现自己ko.observable在设置我的viewmodel时很快就远离了键入,而只是定义了一个对象文字,并通过映射插件传递给它
var viewModel = ko.mapping.fromJS(data);
Run Code Online (Sandbox Code Playgroud)
或者至少,将所有数据填充到viewModel上的属性中,就像这样
var viewModel = {
... events etc ... ,
"data": ko.mapping.fromJS(data)
}
Run Code Online (Sandbox Code Playgroud)
说实话,我一直这样做的主要原因是为了解决必须打字ko.observable和ko.observableArray重复的问题.我只是想弄清楚这是否是一个好方法,如果有任何缺点,将var x = ko.observable()所有特定声明放在一起.此外,我正在加载所有这些,而不是响应任何ajax调用等,从我可以看出,这是映射插件的设计目的.
在使用knockout的工作中,你是否仍然手动逐个声明observable,或者你使用了我使用的mapping.fromJS方法?像这样经常使用映射插件有什么特别的缺点吗?
编辑:
在本文中,Steve通过这样做来设置他的viewModel
var initialData = [ { ... } , { ... } ]; // json from the serializer
var viewModel = {
gifts : ko.observableArray(initialData)
};
Run Code Online (Sandbox Code Playgroud)
通常,我也只是ko.mapping.fromJS用于这种情况,特别是为了确保数组中的对象也被转换为可观察对象.看看他做了什么,我的做法似乎有些过度,并增加了一些不必要的开销.
我有一个庞大,复杂的页面,严重依赖于knockout.js.性能开始成为一个问题,但检查调用堆栈并试图找到瓶颈是一个真正的挑战.
我注意到另一个问题(Knockout.js - 理解foreach和with),接受的答案有评论:
......我建议不要使用
with因为开销而需要高性能的地方......
假设该陈述是真的,这是非常有用的东西要知道,我没有找到这种性能提示的来源.
因此,我的问题是:
在深入了解经典性能调优之前,是否有适用于帮助我的应用程序性能的一般指南/重要提示.
有没有办法将JSON数据对象映射到可观察数组,然后将可观察数组的每个项初始化为特定类型的视图模型?
我已经查看了所有淘汰赛的文档以及这里的淘汰赛和映射示例,我找不到任何适用于我所追求的答案.
所以,我有以下JSON数据:
var data = {
state : {
name : 'SD',
cities : [{
name : 'Sioux Falls',
streets : [{
number : 1
}, {
number : 3
}]
}, {
name : 'Rapid City',
streets : [{
number : 2
}, {
number : 4
}]
}]
}
};
Run Code Online (Sandbox Code Playgroud)
我有以下视图模型:
var StateViewModel = function(){
this.name = ko.observable();
this.cities = ko.observableArray([new CityViewModel()]);
}
var CityViewModel = function(){
this.name = ko.observable();
this.streets = ko.observableArray([new StreetViewModel()]);
}
var StreetViewModel …Run Code Online (Sandbox Code Playgroud) 我使用Knockout.js作为MVVM库将我的数据绑定到某些页面.我目前正在构建一个库来对Web服务进行REST调用.我的RESTful Web服务返回一个简单的结构:
{
id : 1,
details: {
name: "Johnny",
surname: "Boy"
}
}
Run Code Online (Sandbox Code Playgroud)
我有一个可观察的主要父母,myObject.当我做
myObject(ko.mapping.fromJS(data))
Run Code Online (Sandbox Code Playgroud)
可观测量myObject是:
idnamesurname我怎样才能details(理论上结构中的任何对象都是可观察的)?我需要这种行为,这样我就可以在细节上设置一个计算的observable,并在任何内部数据发生变化时立即注意到.
我已经设置了一个基本的递归函数,应该可以解决这个问题.当然,myObject.details它不会成为可观察的.
// Makes every object in the tree an observable.
var makeAllObservables = function () {
makeChildrenObservables(myObject);
};
var makeChildrenObservables = function (object) {
// Make the parent an observable if it's not already
if (!ko.isObservable(object)) {
if ($.isArray(object))
object = ko.observableArray(object);
else
object = ko.observable(object);
}
// Loop through its …Run Code Online (Sandbox Code Playgroud) javascript mvvm knockout-mapping-plugin knockout-2.0 knockout.js
反正我是否可以告诉淘汰映射插件订阅所有属性更改调用某个函数?
我意识到我可以用这种方式手动订阅属性更改事件:
var viewModel = {
name: ko.observable('foo'),
}
// subscribe manually here
viewModel.name.subscribe(function(newValue){
// do work
})
Run Code Online (Sandbox Code Playgroud)
我希望能够一般订阅,因为我的视图模型可能会有所不同,我不想硬编码属性名称.我创建了一个执行此操作的函数,但它可能不是最好的方法.它适用于IE7及以下版本的所有浏览器.
在这里,我将viewmodel作为参数,并尝试反映它订阅属性:
function subscribeToKO(data) {
$.each(data, function (property, value) {
if (getType(value) == "Object")
data[property] = subscribeToKO(value);
else if (getType(value) == "Array") {
$.each(value, function (index, item) {
item = subscribeToKO(item);
});
}
else {
if (value.subscribe) {
value.subscribe(function (newValue) {
// do work
});
}
}
});
return data;
}
Run Code Online (Sandbox Code Playgroud)
就像我说的那样有效,但由于我正在使用映射插入,我希望有一个钩子,我可以使用它来提供一个通常会订阅属性更改的函数.
就像是:
mapping = {
create: function(options){
options.data.subscribe(function(newValue){
// do work …Run Code Online (Sandbox Code Playgroud) 使用knockout mapping插件(http://knockoutjs.com/documentation/plugins-mapping.html)可以映射一个深层次的层次对象吗?
如果我有一个具有多个级别的对象:
var data = {
name: 'Graham',
children: [
{
name: 'Son of Graham',
children: [
{
name: 'Son of Son of Graham',
children: [
{
... and on and on....
}
]
}
]
}
]
}
Run Code Online (Sandbox Code Playgroud)
如何在javascript中将其映射到我的自定义类:
var mapping = {
!! your genius solution goes here !!
!! need to create a myCustomPerson object for Graham which has a child myCustomerPerson object
!! containing "Son of Graham" and that child object contains a …Run Code Online (Sandbox Code Playgroud) 这是我的情景.我正在使用knockout映射插件为我创建一个可观察的viewmodel层次结构.我的层次结构中嵌套了元素.在层次结构中的特定点,我想放置一个Add按钮,在observablearray中插入该元素的新空白副本.问题是我不能只说whatArray.push(new MyObject()).
由于映射插件实际上为我创建了整个层次结构,因此我无法访问"MyObject".所以我似乎唯一可以做的就是插入一个新项目来查看前一个项目并复制它.我尝试了ko.utils.extend函数,但这似乎并没有成为一个真正的克隆.它给了我一个对象,但是当我更新该对象时,它仍然会影响它从中复制的原始对象.
参见jsfiddle 示例
我正在尝试将验证附加到映射视图.我正在使用Knockout Mapping and Validation插件.少女模特儿:
Person {
int Id;
string Name;
Book[] Books;
}
Book {
int Id;
string Name;
}
Run Code Online (Sandbox Code Playgroud)
使用Javascript:
function viewModel() {
var self = this;
self.persons = ko.observableArray();
// persons are retrieved via AJAX...
ko.mapping.fromJS(persons, {}, self.persons);
}
jQuery(function( $ ) {
ko.applyBindings(new viewModel());
});
Run Code Online (Sandbox Code Playgroud)
如何扩展observableArray人员以设置验证规则和消息?我需要验证人员和书籍子数组属性.我发现只有使用显式模型设置的示例,没有自动映射,例如:
Name: ko.observable().extend({ required: true })
Run Code Online (Sandbox Code Playgroud)
然后我需要设置ko.validatedObservable,isValid和validation.init,但我真的不知道如何处理/组织这个.你能帮忙吗?
knockout.js ×10
javascript ×4
mvvm ×4
knockout-2.0 ×2
data-binding ×1
jquery ×1
json ×1
mapping ×1
performance ×1