基于下拉值显示内容的淘汰赛问题

时间:2013-08-18 00:10:20

标签: javascript knockout.js typescript

我刚刚创建了一个jsfiddle,以便您可以快速编辑 JSFIDDLE Link to Code

正如您所看到的,Array selectedChoice在下拉列表中工作正常,并根据下拉列表选择值显示内容。

然而,当我尝试使用具有属性id和名称的CountryModel时,它在Internet Explorer中是错误的,而在Firefox中却没有。但奇怪的是,默认行为不是隐藏内容<p>This content appear when US is selected</p>

我怀疑这段代码  

    <section data-bind="visible: selectedChoiceWithModel().name==='US'"> 

我也试过这个

<section data-bind="if: selectedChoiceWithModel().name === 'Russia', 
     hasfocus: selectedChoiceWithModel().name === 'Russia'">
    <p>This content appear when Russia is selected</p>

两个问题:

enter image description here

打字稿代码

class CountryModel {
    id: number;
    name: string;

}

编译到

var CountryModel = (function () {
    function CountryModel() {
    }
    return CountryModel;
})();

打字稿代码 /// /// ///

class ViewModel {
    constructor()
    {
        //initialize the data for the model now this has two purposes. Consider separating the model from its data generation. 
        var x = new CountryModel();
        x.id = 1;
        x.name = "Russia";
        var y = new CountryModel();
        y.id = 2;
        y.name = "US";
        this.countries.push(x);
        this.countries.push(y);
    }

    availableDrugs = ['A', 'B', 'others'];
    firstName: KnockoutObservable<string>  = ko.observable();
    isVisible: KnockoutObservable<boolean> = ko.observable(true); 
    selectedChoice = ko.observable();
    selectedChoiceWithModel = ko.observable();
    countries: KnockoutObservableArray<CountryModel> = ko.observableArray([]);
    sendMe = function () {

        alert(ko.toJSON({ selectedCountryId: this.selectedChoice() }));
    };
}


$(() => {
    ko.applyBindings(new ViewModel(), document.getElementById("model"));
});

编译到

/// <reference path="CountryModel.ts" />
/// <reference path="../Scripts/typings/knockout/knockout.d.ts" />
/// <reference path="../Scripts/typings/jquery/jquery.d.ts" />
var ViewModel = (function () {
    function ViewModel() {
        this.availableDrugs = ['A', 'B', 'others'];
        this.firstName = ko.observable();
        this.isVisible = ko.observable(true);
        this.selectedChoice = ko.observable();
        this.selectedChoiceWithModel = ko.observable();
        this.countries = ko.observableArray([]);
        this.sendMe = function () {
            alert(ko.toJSON({ selectedCountryId: this.selectedChoice() }));
        };
        //initialize the data for the model now this has two purposes. Consider separating the model from its data generation.
        var x = new CountryModel();
        x.id = 1;
        x.name = "Russia";
        var y = new CountryModel();
        y.id = 2;
        y.name = "US";
        this.countries.push(x);
        this.countries.push(y);
    }
    return ViewModel;
})();

$(function () {
    ko.applyBindings(new ViewModel(), document.getElementById("model"));
});

Html代码

<!--http://jsfiddle.net/pkysylevych/dqUAz/2/
    http://stackoverflow.com/questions/12516123/use-knockout-to-hide-display-questions-based-on-selected-value-in-drop-down
    http://jsbin.com/egacil/2/edit
    http://www.codeproject.com/Articles/342244/Knockout-that-cascading-dropdown

    -->
@section scripts
{
    <script src="~/js/RequestFormModel.js"></script>
    <script src="~/js/CountryModel.js"></script>
}
<div id="model">

<p>First name: <strong data-bind="text: firstName"></strong></p>


<p>First name: <input data-bind="value: firstName" /></p>

   <input type="checkbox" data-bind="checked: isVisible"/>
   <div data-bind="if: isVisible">Hide this content.</div>

        <!--Display content usign observable array--> 
    <select data-bind="options: availableDrugs, value: selectedChoice, optionsCaption: 'choose..'"></select> 
      <input type="text" data-bind="value: firstName, visible: selectedChoice() === 'others', hasfocus: selectedChoice() === 'others'" /> 


    <section data-bind="visible: selectedChoice() === 'A', hasfocus: selectedChoice() === 'A'">
        <p> This content appear when a is selected</p>

    </section>
    <section data-bind="visible: selectedChoice() === 'B', hasfocus: selectedChoice() === 'B'">
        <p>This content appear when B is selected</p>
    </section>




    <!---Sample number two with models instead of just an array --> 
      <select data-bind="options: countries, optionsText: 'name', value: selectedChoiceWithModel, optionsCaption: 'Choose...'"></select>



            <section data-bind="visible: selectedChoiceWithModel().name==='US'">
            <p>This content appear when US is selected</p>
    </section>


</div>

2 个答案:

答案 0 :(得分:1)

我怀疑你的绑定正在破坏,而不是在其他更好的浏览器中,因为一个案例错误,即无法处理。

hasFocus绑定是camelCase,所以尝试将所有的hasfocus绑定转换为hasFocus。

修改

好吧,你的问题不止一个 -

http://jsfiddle.net/BJhQz/14/

在尝试绑定到其上的属性之前,您需要确保已定义selectedChoiceWithModel。我在您的视图中添加了一个无容器绑定,以防止在未选中时查看其名称。

接下来,我对您的视图模型进行了一些更新,以便我更容易理解。我并不是说它们是必需的,但如果没有它们,你的视图模型就会因为我无法阅读它而受到影响。

StackOverflow.com需要一些代码,所以这里是 -

<!-- ko if: selectedChoiceWithModel() -->
    <section data-bind="visible: $data.selectedChoiceWithModel().name() === 'Russia'">
        <p>This content appear when Russia is selected</p>
    </section>
    <h1 data-bind="text: selectedChoiceWithModel().name()"></h1>
<!-- /ko -->

答案 1 :(得分:0)

首先,我非常感谢大家的帮助。您确实帮我识别了代码中的一些问题。我已经完成了代码,这是未来人们可能会遇到和我一样痛苦的结果。我想指出selectedModelWirhChoice()。name()是错误的方法。相反,关键是放置optionsValue:'name',以便selectedChoiceWithModel()绑定到属性名称。当然,人们也可以选择做以下事情  optionsValue:'id'绑定到id号。

JsFiddle Code for your convenience

为了您的方便,我已经包含了完整的JSFiddle,但不幸的是,它将显示已编译的JavaScript而不是干净的Typescript代码。在任何情况下,打字稿代码都在......

之下
<html>
<head>
    <script src="~/js/RequestFormModel.js"></script>
    <script src="~/js/CountryModel.js"></script>
</head>
<body>
<div id="model">

<p>First name: <strong data-bind="text: firstName"></strong></p>


<p>First name: <input data-bind="value: firstName" /></p>

   <input type="checkbox" data-bind="checked: isVisible"/>
   <div data-bind="if: isVisible">Hide this content.</div>

        <!--Display content usign observable array--> 
    <select data-bind="options: availableDrugs, value: selectedChoice, optionsCaption: 'choose..'"></select> 
      <input type="text" data-bind="value: firstName, visible: selectedChoice() === 'others', hasFocus: selectedChoice() === 'others'" /> 


    <section data-bind="visible: selectedChoice() === 'A', hasFocus: selectedChoice() === 'A'">
        <p> This content appear when a is selected</p>

    </section>
    <section data-bind="visible: selectedChoice() === 'B', hasFocus: selectedChoice() === 'B'">
        <p>This content appear when B is selected</p>
    </section>




    <!---Sample number two with models instead of just an array --> 
      <select data-bind="options: countries, optionsText: 'name', optionsValue: 'name', value: selectedChoiceWithModel, optionsCaption: 'Choose...'"></select>



        <span data-bind="text: selectedChoiceWithModel() ? selectedChoiceWithModel() : 'This content is displayed when the value is unknown'"></span>.


     <span data-bind="if:selectedChoiceWithModel()==='Russia'">Content is displayed when Russia is selected</span>
         <span data-bind="if: selectedChoiceWithModel() === 'US'">Content is displayed when US is selected</span>
</div>




 <h1>Keep in mind i used typescript to generate the javascript</h1>

</body>
</html>
class CountryModel {

    public id: number;
    public name: string;

}


/// <reference path="CountryModel.ts" />
/// <reference path="../Scripts/typings/knockout/knockout.d.ts" />
/// <reference path="../Scripts/typings/jquery/jquery.d.ts" />

class ViewModel {
    constructor()
    {
        //initialize the data for the model now this has two purposes. Consider separating the model from its data generation. 
        var x = new CountryModel();
        x.id = 1;
        x.name = "Russia";
        var y = new CountryModel();
        y.id = 2;
        y.name = "US";
        this.countries.push(x);
        this.countries.push(y);

    }

    availableDrugs = ['A', 'B', 'others'];
    firstName: KnockoutObservable<string>  = ko.observable();
    isVisible: KnockoutObservable<boolean> = ko.observable(true); 
    selectedChoice = ko.observable();
    selectedChoiceWithModel = ko.observable();
    countries: KnockoutObservableArray<CountryModel> = ko.observableArray([]);
    sendMe = function () {

        alert(ko.toJSON({ selectedCountryId: this.selectedChoice() }));
    };
}


$(() => {
    ko.applyBindings(new ViewModel(), document.getElementById("model"));
});