Knockout.js - 使用之前的<select>值加载JSON数据

时间:2016-06-07 19:56:34

标签: asp.net-mvc knockout.js

我使用Knockout 2.2为UI编写了一个ASP.NET MVC 4应用程序。其中一个页面有一个由下拉列表填充的简单表,其选定值作为参数传递给AJAX调用。 测试人员提醒我一些奇怪的行为:如果用户在下拉列表中选择一个值,然后转到另一个页面并使用浏览器的后退或前进按钮返回,则所选值将保留在下拉列表中,但参数已通过AJAX调用是下拉选项数组中第一个元素的值,因此表中显示的数据不是用户期望的。 这是我的代码的简化版本: &lt; div style =&#34; text-align:center&#34;&gt;     选项:     &lt; select data-bind =&#34; options:options,optionsText:&#39; Value&#39;,optionsValue:&#39; Key&#39;,value:selectedOption&#34;&gt;&lt; / select&gt; &LT; / DIV&GT; @ * JSON表示viewmodel用于调试目的* @ &LT; DIV&GT;     &lt; textarea style =&#34; margin-top:10px&#34;行=&#34; 20&#34; COLS =&#34; 100&#34; data-bind =&#34; value:ko.toJSON($ root,null,2)&#34;&gt;&lt; / textarea&gt; &LT; / DIV&GT; &lt; script type =&#34; text / javascript&#34;&gt;     var ViewModel = function(){         var self = this;         self.selectedOption = ko.observable();         self.testArray = ko.observableArray();         self.options = ko.observableArray([             {Key:1,Value:&#34; 1&#34; },             {Key:2,Value:&#34; 2&#34; },             {Key:3,Value:&#34; 3&#34; },             {Key:4,Value:&#34; 4&#34; },             {Key:5,Value:&#34; 5&#34; }         ]);         ko.computed(function(){             if(!isNaN(self.selectedOption())){                 $ .getJSON(&#34; @ Url.Action(&#34; GetTestArray&#34;,&#34; Home&#34;)&#34;,{optionId:self.selectedOption()},function(data) {                     self.testArray([self.selectedOption(),2,3]);                 })             }         });     }     var viewModel = new ViewModel();     ko.applyBindings(视图模型); &LT; /脚本&GT; 如果我在计算的observable中注释掉$ .getJSON调用并且只是设置数组(在真实应用程序中,它是自定义业务对象的集合),testArray会按预期显示。但是,如果我将调用包含在服务器中,则即使在下拉列表中最初选择了1以外的数字,testArray也始终显示为[1,2,3]。如果此时选择了不同的值,则observable会按预期更新。 我遇到了&#39; valueWithInit&#39;解决方案:http://jsfiddle.net/rniemeyer/BnDh6/,但我无法让它解决我的问题。我认为原因是element.value属性是&#34;&#34;当第一次调用init函数时,可能是因为下拉列表没有填充选项observable数组。 我已经能够通过强制下拉默认为页面加载的第一个选项来解决问题,但我仍然很想知道是否有可能获得之前选择的下拉列表值和用它执行AJAX调用。

1 个答案:

答案 0 :(得分:0)

首先,关于显示以前选择的值的浏览器,您可以尝试修改<form>标记以禁用自动填充

<form autocomplete="off"></form>

我认为您还可以将此属性添加到单个表单元素中,因此您可能更愿意仅将其添加到<select>元素。

我不认为有问题的浏览器是Safari,是吗?我在过去发现,虽然大多数浏览器都会缓存从服务器加载的文档,但Safari会缓存您导航过的文档。

因此,我在一个MVC控制器上有以下内容,这个页面导致了我过去的问题:

Response.ClearHeaders();
Response.AppendHeader("Cache-Control", "no-cache");
Response.AppendHeader("Cache-Control", "private");
Response.AppendHeader("Cache-Control", "no-store");

如果您希望有选择地应用它,您可能希望将上述内容包含在某种浏览器检测if语句中。

现在,对于你的视图模型,ko.computed是一个简化的表示,还是你真的这样声明了?我从未见过以这种方式单独连接的计算

我的建议是删除computedselectedOption观察点添加subscription

self.selectedOption = ko.observable();
self.selectedOption.subscribe(function(val) {

    if (isNaN(val)) {
        return;
    }

    $.getJSON("@Url.Action("GetTestArray", "Home")", { optionId: self.selectedOption() }, function (data) {
        self.testArray([val, 2, 3]);
    })
}

只有在selectedOption可观察值中保存的值发生变化时,才会触发此订阅。