问题描述
我正在学习kickout.js.我之前做了一个示例,我试图通过两种方式对其进行修改:
I am learning knockout.js. I did one example earlier, which I am trying to modify in two ways:
-
我组织了代码以最大程度地减小全局范围,因此在
window
对象中只有一个顶级对象,并将包括模型在内的所有内容都放在其中.
I organized the code to minimize global scope so there's just one top-level object inside the
window
object and I put everything including my model in there.
如果模型不可观察,我想看看在模型更改时text:
绑定是否会更改视图.有关此想法的详细说明,请参见下面的HTML代码中的注释.
I wanted to see if the text:
binding changes the view when the model changes if the model is not an observable. For a finer elaboration of this idea, please see the comments in the HTML code below.
但是,当我运行这段代码时,我得到一个ReferenceError: friend is not defined.
However, when I run this bit of code, I get a ReferenceError: friend is not defined.
我认为是因为我的model
对象不再是window
对象的顶级成员.
I am assuming it is because of the fact that my model
object is no longer a top-level member of the window
object.
是否可以具有这样的模型层次结构,并使其与剔除一起工作?
Is it possible to have a model hierarchy like this and have it work with knockout?
1a.html
<html>
<head>
<meta charset="utf-8"/>
<script type='text/javascript' src='knockout-3.4.0.js'></script>
</head>
<!-- The purpose of this program is to find out whether just a
text: binding also changes the display / view if the model changes.
Meaning if I explicitly do not create an observable out of a model property
and use only a text: binding, does the property still behave like an observable?
To do this, I am using the same code as 1.html and 1.js,
except for one change. I am adding another set of textboxes
in which I will type in a new first name and last name.
Then, I will click the "Update Name" button
in whose listener, I will update the model properties friend.firstName
and friend.lastName.
Then, I'd like to see if the text box values for txtFirstName and txtLastName
change.
-->
<body>
<form id = "frm" name = "frm">
<fieldset>
<legend>Your friend's basic information:</legend>
<div>
<label for = "FirstName">First Name</label>
<input type = "text" name = "FirstName" id = "txtFirstName" data-bind = "value: friend.firstName" />
</div>
<div>
<label for = "LastName">Last Name</label>
<input type = "text" name = "LastName" id = "txtLastName" data-bind = "value: friend.lastName" />
</div>
<fieldset>
<legend>New Information:</legend>
<div>
<label for = "NewFirstName">New Value for First Name</label>
<input type = "text" name = "NewFirstName" id = "txtNewFirstName" />
</div>
<div>
<label for = "NewLastName">New Value for Last Name</label>
<input type = "text" name = "NewLastName" id = "txtNewLastName" />
</div>
</fieldset>
<div>
<input type = "button" value = "Update Name" id = "btnUpdateName" name = "Save" />
</div>
</fieldset>
</form>
<script type='text/javascript' src='1a.js'></script>
</body>
</html>
1a.js
var ThisDocument = function()
{
this.model =
{
friend :
{
firstName : 'Sathyaish',
lastName : 'Chakravarthy'
}
};
this.init = function()
{
wire(window, "load", wireElementHandlers);
};
function wire(element, eventName, listener)
{
var ie = document.all ? true : false;
if (!element) throw new Error("Element " + element + " not found.");
if (ie)
{
element.attachEvent("on" + eventName, listener);
}
else
{
element.addEventListener(eventName, listener, false);
}
};
function wireElementHandlers()
{
var btnUpdateName = document.getElementById('btnUpdateName');
wire(btnUpdateName, "click", changeName);
ko.applyBindings(this.model);
};
function changeName(event)
{
var firstName = document.getElementById('txtNewFirstName').value;
var lastName = document.getElementById('txtNewLastName').value;
this.model.friend.firstName = firstName;
this.model.friend.lastName = lastName;
};
};
var thisDocument = new ThisDocument();
thisDocument.init();
使模型成为窗口内的顶级对象
但是,如果我使模型成为window
对象中的顶级成员,则代码可以正常工作,并且我知道上面的HTML注释和项目符号#2中描述的问题的答案.以上.
If, however, I make the model a top-level member inside the window
object, the code works fine and I get to know the answer to my question described in the HTML comments above and in the bullet point #2 above.
答案是:不.如果没有可观察的内容,当模型更改时,简单的text:
绑定不会更新视图.
The answer is: no. Without having an observable, a simple text:
binding does not update the view when the model changes.
以下是将模型作为顶层对象的代码:
Here is the code with the model as the top-level object:
1a.js
this.model =
{
friend :
{
firstName : 'Sathyaish',
lastName : 'Chakravarthy'
}
};
var ThisDocument = function()
{
this.init = function()
{
wire(window, "load", wireElementHandlers);
};
function wire(element, eventName, listener)
{
var ie = document.all ? true : false;
if (!element) throw new Error("Element " + element + " not found.");
if (ie)
{
element.attachEvent("on" + eventName, listener);
}
else
{
element.addEventListener(eventName, listener, false);
}
};
function wireElementHandlers()
{
var btnUpdateName = document.getElementById('btnUpdateName');
wire(btnUpdateName, "click", changeName);
ko.applyBindings(model);
};
function changeName(event)
{
var firstName = document.getElementById('txtNewFirstName').value;
var lastName = document.getElementById('txtNewLastName').value;
model.friend.firstName = firstName;
model.friend.lastName = lastName;
};
};
var thisDocument = new ThisDocument();
thisDocument.init();
因此,我怀疑this
指针被弄乱了.
Therefore, my suspicion is that the this
pointer is being messed up.
applyBindings
方法是否有重载,或者如果不是重载,则可能是另一种方式,它允许我告诉敲除绑定模型时使用特定对象作为this
参数?
Is there an overload for the applyBindings
method or may be another way if not an overload that allows me to tell knockout to use a particular object as the this
parameter when binding a model?
例如
var MyDocument = function()
{
var model =
{
friend : { firstName: 'Sathyaish', lastName: 'Chakravarthy' }
};
this.init : function()
{
ko.applyBindings(this.model /*, but this may lead knockout
to not be able to discover my model, as my experience so far
shows. I need to recalibrate the 'this' pointer so knockout
knows to look for the model object inside whatever I tell it to,
i.e. inside an instance of the MyDocument class and not inside
whatever the this pointer happens to reference when knockout
is performing the binding. */);
};
}
var myDocument = new MyDocument();
myDocument.init();
推荐答案
我认为您确实需要映射插件,并且要更改/输入值需要这样做:
I think you really need the mapping plugin and to change/put a value will need to do:
model.friend.firstName(firstName)
稍后我将尝试您的代码,如果有必要,我将编辑我的答案.
I will try your code later and if is necessary i will edit my answer.
这篇关于如果模型不是顶级对象,如何将模型绑定到模型中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!