2016-01-01 25 views
1

我有一个引导程序导航标签页,我想在选择标签页时动态显示内容。每个选项卡必须显示一个div,其中包含一些文本,这些文本是通过控制器的动作GetSection()从ajax调用返回的。使用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()); 

的问题是,retValue从阿贾克斯不会显示。该控制器操作是这样的:

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

回答

1

淘汰赛只能知道更新是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 
     } 
    }); 

最后,如果你绑定到您的视图复杂表达式,你需要调用它的函数(没有参数),以获得值:

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

作为一个边注意,意识到,如果绑定直奔只是观察到的,可以去掉括号(考虑从淘汰赛语法糖),例如:

<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),该函数

所以bascially,当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> 

clickselectChild方法将以上下文数据为参数再次被调用。

+0

它是如何工作的数据绑定点击,因为$ parent.selectedSection不是一些功能? – albert

+0

这本身就是一个真正的问题,但我试图在我的答案的脚注中解决它。如果您需要进一步澄清,我建议您提出一个新的SO问题(可能首先搜索现有问题)。 – Jeroen

-1

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

这样做 self.selectedSection(data);

+0

这本身就会*不*工作,因为'retValue'在OP代码中不是可观察的。 – Jeroen