[英]How to bind a model to knockout if the model is not a top-level object?
I am learning knockout.js. 我正在学习knockout.js。 I did one example earlier , which I am trying to modify in two ways:
我之前做了一个示例 ,尝试通过两种方式进行修改:
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. 我组织了代码以最小化全局范围,因此
window
对象中只有一个顶级对象,并且将包括模型在内的所有内容都放在了其中。
I wanted to see if the text:
binding changes the view when the model changes if the model is not an observable. 我想看看如果模型不可观察时,当模型更改时,
text:
绑定是否会更改视图。 For a finer elaboration of this idea, please see the comments in the HTML code below. 有关此想法的详细说明,请参见下面的HTML代码中的注释。
However, when I run this bit of code, I get a ReferenceError: friend is not defined.
但是,当我运行这段代码时,出现了
ReferenceError: friend is not defined.
I am assuming it is because of the fact that my model
object is no longer a top-level member of the window
object. 我假设是因为我的
model
对象不再是window
对象的顶级成员。
Is it possible to have a model hierarchy like this and have it work with knockout? 是否可以具有这样的模型层次结构并使其与剔除一起工作?
1a.html 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 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();
Making the Model a Top-Level Object Inside Window 使模型成为窗口内的顶级对象
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. 但是,如果我使模型成为
window
对象内的顶级成员,则代码可以正常工作,并且我知道上面HTML注释和上面第2点中描述的问题的答案。
The answer is: no. 答案是不。 Without having an observable, a simple
text:
binding does not update the view when the model changes. 如果没有可观察的内容,则简单的
text:
绑定不会在模型更改时更新视图。
Here is the code with the model as the top-level object: 这是将模型作为顶层对象的代码:
1a.js 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();
Therefore, my suspicion is that the this
pointer is being messed up. 因此,我怀疑
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? applyBindings
方法是否有重载,或者如果不是重载,则可能是另一种方式,它允许我告诉敲除绑定模型时使用特定对象作为this
参数?
For eg 例如
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. 稍后,我将尝试您的代码,如有必要,我将编辑我的答案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.