Knockout js:无法从数组内的表单中写入值

时间:2014-08-14 04:12:11

标签: javascript arrays knockout.js ko.observablearray

我有一个生成表单数组的脚本,每个表单都会影响下一个表单的可用选项。令人敬畏的martin booth解决了在添加新表单时更新显示值的问题。

但是,我有一个可观察的数组(defaultSampleRates),它位于表单数组之外,对于我的生命,我无法获得将项目推送到该数组中的表单。我尝试用十几种不同的方式在十几个不同的地方宣布它,但它只是不会坚持。

基本上我需要'默认采样率'下拉列表显示在上面的表格中选择的采样率(用户必须只能从显示的一个中选择默认采样率,而不是从完整列表中选择)。

任何提示很多helpo脑痛。在这里摆弄:http://jsfiddle.net/3lliot/9vsa4hh7/

HTML:

<body>
    <div style="float:left; width:60%">
        <div data-bind="foreach: forms">
            <div style="float:left; margin-right:20px"> <span> 

            <!-- This is a *view* - HTML markup that defines the appearance of your UI -->

            <p><span style="color:#AB0002">Sample rate element <span data-bind="text: formNum"></span></span>
                </p>
                <p>Sample rate (Hz):
                    <select data-bind="options: sampleRates, value: selectedSampleRate"></select>
                </p>
                </span>
            </div>
        </div>
        <div style="float:left; clear:both; margin-bottom:20px">
            <hr/>
            <button data-bind="click: addForm">Add &lt;srate&gt; element</button>
            <button data-bind="click: removeForm">Remove</button>
            <p>Default sample rate:
                <select data-bind="options: defaultSampleRates, value: selectedDefaultSampleRate"></select>
            </p>
        </div>
    </div>
    <div style="float:right; width:38%; overflow:scroll; border-left:thin; border-left-style:solid; border-left-color:#dfdfdf;padding-left: 1%"> <span class="code">&lt;audio&gt;</span>

        <ul data-bind="foreach: forms">
            <li>
                <!-- render the json --> <span class="code">&nbsp;&nbsp;&lt;srate id="<span data-bind="text: formNum"></span>"&gt;
                <br/>&nbsp;&nbsp;&nbsp;&nbsp;&lt;sample_rate&gt;<span data-bind="text: selectedSampleRate"></span>&lt;&#47;sample_rate&gt;
                <br/>&nbsp;&nbsp;&lt;&#47;srate&gt;</span>
            </li>
        </ul> <span class="code">&nbsp;&nbsp;&lt;default_srate&gt;<span data-bind="text: selectedDefaultSampleRate"></span>&lt;&#47;default_srate&gt;</span>
        <br/><span class="code">&lt;&#47;audio&gt;</span>

    </div>
</body>

JS:

// This is a simple *viewmodel* - JavaScript that defines the data and behavior of your UI
//window.onload = startKnockout;
window.onload = startKnockout;
var formNum;
var i = -1;
var selectedSampleRates = [];

function Form(allSampleRates, forms) {
    var self = this;
    // Declare observables
    self.selectedSampleRate = ko.observable();
    self.formNum = ko.observable();

    self.sampleRates = ko.computed(function () {
        var formsValue = forms(),
            availableSampleRates = ko.utils.arrayFilter(allSampleRates, function (sampleRate) {
                return !ko.utils.arrayFirst(formsValue, function (form) {
                    if (form != self) {
                        if (form.selectedSampleRate() === sampleRate) {
                            if (selectedSampleRates.indexOf(sampleRate) === -1) {
                                selectedSampleRates.push(sampleRate);
                            }
                        }

                        return form.selectedSampleRate() === sampleRate;
                    } else {
                        return form != self;
                    }
                });
            });
        return availableSampleRates;
    });

    // count how many srate elements there are 
    i++;
    self.formNum = i;
}

var Vm = function () {
    var self = this;
    var item = 0,
        allSampleRates = ['192000', '176400', '96000', '88200', '48000', '44100'];
    // declare observables for options outside the srate elements   
    self.selectedDefaultSampleRate = ko.observable();

    // add remove forms stuff
    self.forms = ko.observableArray([]);
    self.forms.push(new Form(allSampleRates, self.forms));
    item++;
    self.addForm = function () {
        if (i < 5) {
            self.forms.push(new Form(allSampleRates, self.forms));
            item++;

        } else {
            alert("Can't have more than 6 <srate> elements!")
        }
    };
    self.removeForm = function () {
        if (item > 1) {
            self.forms.splice(item - 1, 1);
            item--;
            i--;
        } else {
            alert("Must have at least one <srate> element!")
        }
    };
    // define arrays for options outside srate elements
    self.defaultSampleRates = ko.observableArray([]);
    return self;
}

// Activates knockout.js
    function startKnockout() {
        ko.applyBindings(new Vm());
    };

1 个答案:

答案 0 :(得分:0)

您可以使用selectedOptions绑定来添加defaultSample速率。

我将选择sampleRates代码更改为此

<select data-bind="options: sampleRates, value: selectedSampleRate, selectedOptions: $root.defaultSampleRates"></select>

注意selectedOptions绑定那里..

应该按照您的需要工作。

更新了 小提琴演示:http://jsfiddle.net/rahulrulez/9vsa4hh7/3/

我希望你想要的是什么。