Knockout.js 和选择列表不更新 Jquery 模板中的属性
我不确定为什么我的依赖可观察 URL 没有在选择列表更改时更新。 iframe 应更新选择更改事件上的 url,但没有任何反应。虽然依赖的可观察量是这样的,但是模板没有被更新。它在没有模板的情况下仅使用静态定义的 HTML 工作,但不是我尝试创建模板并且 iframe 不更新。
查看
@model AvatarViewModel
@{
ViewBag.Title = "Index";
Layout = "~/Areas/Admin/Views/Shared/_AdminLayout.cshtml";
}
<div data-bind='template: { name: "editableAgentTemplate", data: caseStudy.instructor }'>
</div>
<div data-bind='template: { name: "editableAgentTemplate", data: caseStudy.assistantInstructor }'>
</div>
<div data-bind='template: { name: "editableAgentTemplate", data: caseStudy.opponent }'>
</div>
<script id="editableAgentTemplate" type="text/html">
<div>
<div>
<iframe style="width: 125px; height: 100px; border: none" scrolling="no" frameborder="0"
data-bind="attr: { id: name, name: name, src: url }">
</iframe>
</div>
<select data-bind="options: agents, optionsText: 'Title', optionsValue: 'Id', value: selectedId,">
</select>
<button data-bind="click: function() { caseStudy.saveAvatar(name, id) }">
Update
</button>
<input type="text" data-bind="value: text" />
<button data-bind="click: function() { app.viewModel.caseStudy.speak(text, name) }">
Speak
</button>
</div>
</script>
@section Script {
<script src="/Scripts/app.avatars.js" type="text/javascript"></script>
<script src="/Areas/Admin/Scripts/app.admin.casestudy.avatars.js" type="text/javascript"></script>
<script type="text/javascript">
app.avatars.init(@Html.Raw(@Model.Avatars.ToJson()));
app.admin.caseStudy.init('@ApplicationAvatarType.Instructor.ToString()', '@ApplicationAvatarType.AssistantInstructor', '@ApplicationAvatarType.Opponent');
</script>
}
JS文件
(function (app, $, undefined) {
app.viewModel = app.viewModel || {};
app.admin.caseStudy = app.admin.caseStudy || {};
var controller = '/Admin/CaseStudy/Avatars';
var urls = {
GET_AVATARS: controller + '/GetAvatars',
SAVE_AVATAR: controller + '/SaveAvatar'
};
var editableAgent = function () {
this.id = ko.observable(0);
this.selectedId = ko.observable(0),
this.name = ko.observable('');
this.text = ko.observable('');
this.agents = ko.observableArray();
this.url = ko.dependentObservable(function () {
console.log('url');
if (this.selectedId())
return '/Avatar/Avatar?assetId=' + this.selectedId();
else {
return '';
}
}, this);
};
app.viewModel.caseStudy = {
instructor: ko.observable(new editableAgent()),
assistantInstructor: ko.observable(new editableAgent()),
opponent: ko.observable(new editableAgent()),
agents: ko.observableArray()
};
app.viewModel.caseStudy.speak = function (text, type) {
if (text().length > 0) {
app.avatars.addAction({ AgentName: type(), Text: text(), Speech: text() });
app.avatars.speak();
}
};
app.admin.caseStudy.init = function (instructor, assistantInstructor, opponent) {
app.viewModel.caseStudy.instructor().name(instructor);
app.viewModel.caseStudy.assistantInstructor().name(assistantInstructor);
app.viewModel.caseStudy.opponent().name(opponent);
app.admin.caseStudy.getAvatars(function () {
app.applyBindings();
});
};
app.admin.caseStudy.getAvatars = function (callback) {
var options = {
url: urls.GET_AVATARS,
callback: function (json) {
if (json) {
app.viewModel.caseStudy.agents(json.Avatars);
app.viewModel.caseStudy.instructor().agents(json.Avatars);
app.viewModel.caseStudy.opponent().agents(json.Avatars);
app.viewModel.caseStudy.assistantInstructor().agents(json.Avatars);
app.viewModel.caseStudy.instructor().selectedId(json.Instructor.AssetId);
app.viewModel.caseStudy.opponent().selectedId(json.Opponent.AssetId);
app.viewModel.caseStudy.assistantInstructor().selectedId(json.AssistantInstructor.AssetId);
app.viewModel.caseStudy.instructor().id(json.Instructor.AssetId);
app.viewModel.caseStudy.opponent().id(json.Opponent.AssetId);
app.viewModel.caseStudy.assistantInstructor().id(json.AssistantInstructor.AssetId);
if (typeof (callback) === 'function') {
callback();
}
}
}
};
app.makeRequest(options);
};
app.viewModel.caseStudy.saveAvatar = function (type, assetId) {
var options = {
url: urls.SAVE_AVATAR + '?type=' + type + '&assetId=' + assetId,
callback: function (json) {
if (json) {
alert('Saved');
}
}
};
app.makeRequest(options);
};
})(window.app = window.app || {}, jQuery);
I am not sure why my dependent observable URL is not being updated on a select list change. The iframe should update the url on the select on change event but nothing happens. The dependent observable is being this though, but the template isn't being updated. It worked without the template with just statically defined HTML, but not I tried to create a template and the iframe doesn't update.
View
@model AvatarViewModel
@{
ViewBag.Title = "Index";
Layout = "~/Areas/Admin/Views/Shared/_AdminLayout.cshtml";
}
<div data-bind='template: { name: "editableAgentTemplate", data: caseStudy.instructor }'>
</div>
<div data-bind='template: { name: "editableAgentTemplate", data: caseStudy.assistantInstructor }'>
</div>
<div data-bind='template: { name: "editableAgentTemplate", data: caseStudy.opponent }'>
</div>
<script id="editableAgentTemplate" type="text/html">
<div>
<div>
<iframe style="width: 125px; height: 100px; border: none" scrolling="no" frameborder="0"
data-bind="attr: { id: name, name: name, src: url }">
</iframe>
</div>
<select data-bind="options: agents, optionsText: 'Title', optionsValue: 'Id', value: selectedId,">
</select>
<button data-bind="click: function() { caseStudy.saveAvatar(name, id) }">
Update
</button>
<input type="text" data-bind="value: text" />
<button data-bind="click: function() { app.viewModel.caseStudy.speak(text, name) }">
Speak
</button>
</div>
</script>
@section Script {
<script src="/Scripts/app.avatars.js" type="text/javascript"></script>
<script src="/Areas/Admin/Scripts/app.admin.casestudy.avatars.js" type="text/javascript"></script>
<script type="text/javascript">
app.avatars.init(@Html.Raw(@Model.Avatars.ToJson()));
app.admin.caseStudy.init('@ApplicationAvatarType.Instructor.ToString()', '@ApplicationAvatarType.AssistantInstructor', '@ApplicationAvatarType.Opponent');
</script>
}
JS File
(function (app, $, undefined) {
app.viewModel = app.viewModel || {};
app.admin.caseStudy = app.admin.caseStudy || {};
var controller = '/Admin/CaseStudy/Avatars';
var urls = {
GET_AVATARS: controller + '/GetAvatars',
SAVE_AVATAR: controller + '/SaveAvatar'
};
var editableAgent = function () {
this.id = ko.observable(0);
this.selectedId = ko.observable(0),
this.name = ko.observable('');
this.text = ko.observable('');
this.agents = ko.observableArray();
this.url = ko.dependentObservable(function () {
console.log('url');
if (this.selectedId())
return '/Avatar/Avatar?assetId=' + this.selectedId();
else {
return '';
}
}, this);
};
app.viewModel.caseStudy = {
instructor: ko.observable(new editableAgent()),
assistantInstructor: ko.observable(new editableAgent()),
opponent: ko.observable(new editableAgent()),
agents: ko.observableArray()
};
app.viewModel.caseStudy.speak = function (text, type) {
if (text().length > 0) {
app.avatars.addAction({ AgentName: type(), Text: text(), Speech: text() });
app.avatars.speak();
}
};
app.admin.caseStudy.init = function (instructor, assistantInstructor, opponent) {
app.viewModel.caseStudy.instructor().name(instructor);
app.viewModel.caseStudy.assistantInstructor().name(assistantInstructor);
app.viewModel.caseStudy.opponent().name(opponent);
app.admin.caseStudy.getAvatars(function () {
app.applyBindings();
});
};
app.admin.caseStudy.getAvatars = function (callback) {
var options = {
url: urls.GET_AVATARS,
callback: function (json) {
if (json) {
app.viewModel.caseStudy.agents(json.Avatars);
app.viewModel.caseStudy.instructor().agents(json.Avatars);
app.viewModel.caseStudy.opponent().agents(json.Avatars);
app.viewModel.caseStudy.assistantInstructor().agents(json.Avatars);
app.viewModel.caseStudy.instructor().selectedId(json.Instructor.AssetId);
app.viewModel.caseStudy.opponent().selectedId(json.Opponent.AssetId);
app.viewModel.caseStudy.assistantInstructor().selectedId(json.AssistantInstructor.AssetId);
app.viewModel.caseStudy.instructor().id(json.Instructor.AssetId);
app.viewModel.caseStudy.opponent().id(json.Opponent.AssetId);
app.viewModel.caseStudy.assistantInstructor().id(json.AssistantInstructor.AssetId);
if (typeof (callback) === 'function') {
callback();
}
}
}
};
app.makeRequest(options);
};
app.viewModel.caseStudy.saveAvatar = function (type, assetId) {
var options = {
url: urls.SAVE_AVATAR + '?type=' + type + '&assetId=' + assetId,
callback: function (json) {
if (json) {
alert('Saved');
}
}
};
app.makeRequest(options);
};
})(window.app = window.app || {}, jQuery);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这个问题的全部内容如下: https://github.com/SteveSanderson/knockout/ issues/133
如果您可以在服务器上或 JavaScript 中强制代理 ID 为字符串(id + '' 有效),那么您将不会看到该问题。
另外,根据对代码的一些重组,这似乎在 1.3 中不再是问题。因此,您可能想尝试测试版: http://blog.stevensanderson.com/2011/08/31/knockout-1-3-0-beta-available/
This one has all the makings of this issue here: https://github.com/SteveSanderson/knockout/issues/133
If you can force your agent ids to strings either on the server or in JavaScript (id + '' works), then you will not see the issue.
Also, it appears that based on some reorganization of the code, this is no longer an issue in 1.3. So, you might want to try the beta out: http://blog.stevensanderson.com/2011/08/31/knockout-1-3-0-beta-available/