【问题标题】:Load tabs with Ajax使用 Ajax 加载选项卡
【发布时间】:2016-04-06 06:34:33
【问题描述】:

我有一个引导导航选项卡,我想在选择选项卡时动态显示内容。每个选项卡都必须显示一个带有一些文本的 div,这些文本是在控制器的操作 GetSection() 处从 ajax 调用返回的。

<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 代码:

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没有显示。控制器动作是这样的:

public JsonResult GetSection(string name)
{
    var ret = new { text = name + "abcd" };
    return Json(ret, JsonRequestBehavior.AllowGet);
}

【问题讨论】:

    标签: asp.net-mvc twitter-bootstrap knockout.js


    【解决方案1】:

    Knockout 只能知道为 obsverable(因此得名)的属性更新视图,因此您需要使 retValue 可观察:

    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);
    }
    

    然后,您需要记住设置一个可观察对象的值,方法是将其作为方法调用,并以新值作为唯一参数,例如:

        $.ajax({
            url: '@Url.Action("GetSection")',
            data: { name: self.selectedSection().name },
            type: 'GET',
            success: function (data) {
                self.selectedSection().retValue(data.text);    // <-- change here
            }
        });
    

    最后,如果您要绑定到视图中的复杂表达式,则需要将其作为函数调用(使用 no 参数)以 get 其值:

    <span data-bind="text: 'In section: ' + retValue()" />
    

    作为旁注,如果你直接绑定到 observable,你可以去掉括号(认为它是淘汰赛的语法糖),例如:

    <span data-bind="text: retValue" />
    

    这实际上等同于:

    <span data-bind="text: retValue()" />
    

    在脚注中,我看到您已将此语法用于 click 绑定:

    <a href="#" data-bind="click: $parent.selectedSection">...</a>
    

    这可行...但只是巧合。你应该一起意识到这些事情:

    • $parent.selectedSection 包含ko.observable() 的结果,这意味着它实际上是一个可以调用的函数
    • click 数据绑定将调用它作为函数获得的表达式,将上下文数据(在您的情况下为 Section)传递给该函数

    所以基本上,当click 发生时,会发生:

    $parent.selectedSection($data) // where $data == the current Section
    

    这有效地选择了部分。

    如果$parent 有一个函数会更冗长但更清晰:

    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);
    }
    

    然后以这种清晰的方式使用点击绑定:

    <a href="#" data-bind="click: $parent.selectChild">...</a>
    

    click 上,selectChild 方法将被调用,再次使用上下文数据作为参数。

    【讨论】:

    • 由于 $parent.selectedSection 不是某些功能,数据绑定点击如何工作?
    • 这本身就是一个问题,但我试图在我的答案的脚注中解决它。如果您需要进一步澄清,我建议您提出一个新的 SO 问题(也许先搜索现有问题)。
    【解决方案2】:

    而不是这个 self.selectedSection().retValue=data.text;

    这样做 self.selectedSection(数据);

    【讨论】:

    • 这本身不会起作用,因为retValue 不是在 OP 的代码中可观察到的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-10
    • 2012-12-30
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    相关资源
    最近更新 更多