使用Ajax加载选项卡 [英] Load tabs with Ajax
问题描述
我有一个引导nav标签,我想在选择标签时动态显示内容.每个选项卡必须显示一个div,其中包含一些在控制器的操作GetSection()
中从ajax调用返回的文本.
I have a bootstrap nav-tab and I want to display dynamically content when I select a tab. Each tab must display a div with some text that is returned from ajax call at the controller's action GetSection()
.
<div class="tabbable">
<ul class="nav nav-tabs" data-bind="foreach: sections">
<li data-bind="css: { active: isSelected }">
<a href="#" data-bind="click: $parent.selectedSection">
<span data-bind="text: name" />
</a>
</li>
</ul>
<div class="tab-content" data-bind="foreach: sections">
<div class="tab-pane" data-bind="css: { active: isSelected }">
<span data-bind="text: 'In section: ' + retValue" />
</div>
</div>
</div>
JavaScript代码:
Javascript code:
var Section = function (name, selected) {
this.name = name;
this.retValue = "";
this.isSelected = ko.computed(function () {
return this === selected();
}, this);
}
var ViewModel = function () {
var self = this;
self.selectedSection = ko.observable();
self.sections = ko.observableArray([
new Section('Tab One', self.selectedSection),
new Section('Tab Two', self.selectedSection),
new Section('Tab Three', self.selectedSection)
]);
self.selectedSection(self.sections()[0]);
self.selectedSection.subscribe(function () {
$.ajax({
url: '@Url.Action("GetSection")',
data: { name: self.selectedSection().name },
type: 'GET',
success: function (data) {
self.selectedSection().retValue=data.text;
}
});
});
}
ko.applyBindings(new ViewModel());
问题是来自ajax的retValue
没有显示.控制器的动作是这样的:
The problem is that retValue
from ajax is not displayed. The controller action is this:
public JsonResult GetSection(string name)
{
var ret = new { text = name + "abcd" };
return Json(ret, JsonRequestBehavior.AllowGet);
}
推荐答案
Knockout只能更新视图以查看可观察的属性(因此命名),因此您需要将
Knockout can only know to update the view for properties that are obsverable (hence the name), so you need to make retValue
observable:
var Section = function (name, selected) {
this.name = name; // <-- consider similar change here too
this.retValue = ko.observable(""); // <-- change here
this.isSelected = ko.computed(function () {
return this === selected();
}, this);
}
然后,您需要记住通过以新值作为唯一参数的方法调用它来设置一个可观察对象的值,例如:
Then, you need to remember to set an obsverable's value by calling it as a method with the new value as its only argument, e.g.:
$.ajax({
url: '@Url.Action("GetSection")',
data: { name: self.selectedSection().name },
type: 'GET',
success: function (data) {
self.selectedSection().retValue(data.text); // <-- change here
}
});
最后,如果要绑定到视图中的复杂表达式,则需要将其作为一个函数(带有 no 参数)调用以 get 的值:
And finally, if you're binding to a complex expression in your view you need to invoke it as a function (with no arguments) to get its value:
<span data-bind="text: 'In section: ' + retValue()" />
请注意,如果直接绑定到可观察对象,则可以省略括号(将其视为语法糖),例如:
As a side note, realize that you can leave off the parentheses (consider it syntactic sugar from knockout) if you bind straight to just the observable, e.g.:
<span data-bind="text: retValue" />
实际上等效于:
<span data-bind="text: retValue()" />
在脚注上,我看到您已经将这种语法用于click
绑定:
On a foot note, I see you've used this syntax for a click
binding:
<a href="#" data-bind="click: $parent.selectedSection">...</a>
这有效...但仅出于巧合.您应该一起意识到这些事情:
This works... but only by coincidence. You should realize these things together:
-
$parent.selectedSection
包含ko.observable()
的结果,这意味着它实际上是可以被调用的函数 -
click
数据绑定将调用它作为函数获得的表达式,并将上下文数据(在您的情况下为Section
)传递给该函数
$parent.selectedSection
contains the result ofko.observable()
which means it is in fact a function that can be invoked- the
click
data-binding will invoke the expression it gets as a function, passing the contextual data (in your case aSection
) to that function
基本上,当click
发生时,此发生:
So bascially, when the click
happens, this happens:
$parent.selectedSection($data) // where $data == the current Section
有效选择部分.
如果$parent
具有功能,它将更加冗长,尽管更加清晰:
It would be more verbose though a lot clearer if the $parent
had a function:
var self = this;
self.selectChild = function(section) {
// Possibly handle other things here too, e.g. clean-up of the old selected tab
self.selectedSection(section);
}
然后以这种清晰的方式使用click绑定:
And then use the click binding in this clear way:
<a href="#" data-bind="click: $parent.selectChild">...</a>
在click
上,将再次使用上下文数据作为参数调用selectChild
方法.
On click
the selectChild
method will be called, again with the contextual data as the argument.
这篇关于使用Ajax加载选项卡的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!