knockoutjs - 如何填充空的可观察数组以响应用户操作(锚链接点击)

时间:2014-10-23 17:09:28

标签: knockout.js ko.observablearray

我尝试将元素添加到空的可观察数组以响应用户选择(用户单击链接以将该元素添加到可观察数组)

这是我的ko脚本代码:

function mfProduct(data) {
    var self = this;
    self.MfProductId = data.MfProductId;
    self.MfProductName = data.MfProductName;
};

function mfProductViewModel() {
    // Data
    var self = this;
    self.ProdId = ko.observable();
    self.ProdName = ko.observable();
    self.selectedProducts = ko.observableArray([]);

    // Operations
    self.addProduct = function () {
        if (self.ProdId() != '' && self.ProdId() != undefined) {
            self.selectedProducts.push(new mfProduct({ MfProductId: self.ProdId(), MfProductName: self.ProdName() }));
            self.ProdId("");
            self.ProdName("");
        }
    };

    self.removeProduct = function (mfProduct) {
        self.selectedProducts.remove(mfProduct);
    };
};

这是我的观点标记:

<div class="row">
<div id="selectedProducts" class="col-sm-12" data-bind="foreach: selectedProducts">
    <div class="row" style="border: 1px solid red;">
        <div class="col-sm-10"><strong data-bind="text: MfProductName"></strong></div>
        <div class="col-sm-2"><a href="#" data-bind="click: removeProd"><i class="glyphicon glyphicon-remove-circle"></i></a></div>
    </div>
</div>
<div class="form-group">
    <div class="col-sm-3">
        Select product
    </div>
    <div class="col-sm-offset-3">
        <input type="hidden" id="selectedProdId" data-bind="value: ProdId" value="">
        <input type="hidden" id="selectedProdName" data-bind="value: ProdName" value="">
        <div id="searchResults" class="ddlContents">
            <ul>
                <li><a id="00001" href="#" onmouseover="javascript:markSelected(this);" data-bind="click: addProduct">Milky Way</a></li>
                <li><a id="00002" href="#" onmouseover="javascript:markSelected(this);" data-bind="click: addProduct">Bocadin</a></li>
                <li><a id="00003" href="#" onmouseover="javascript:markSelected(this);" data-bind="click: addProduct">Carlos V</a></li>
                <li><a id="00004" href="#" onmouseover="javascript:markSelected(this);" data-bind="click: addProduct">Snickers</a></li>
                <li><a id="00005" href="#" onmouseover="javascript:markSelected(this);" data-bind="click: addProduct">Crunch</a></li>
                <li><a id="00006" href="#" onmouseover="javascript:markSelected(this);" data-bind="click: addProduct">Power Milch</a></li>
                <li><a id="00007" href="#" onmouseover="javascript:markSelected(this);" data-bind="click: addProduct">Toblerone</a></li>
                <li><a id="00008" href="#" onmouseover="javascript:markSelected(this);" data-bind="click: addProduct">KitKat</a></li>
                <li><a id="00009" href="#" onmouseover="javascript:markSelected(this);" data-bind="click: addProduct">Cacao</a></li>
            </ul>
        </div>
    </div>
</div>

我添加了onmouseover事件处理程序来更新productId和productName的可观察属性,因为我不知道如何将参数发送到点击绑定(类似于javascript:addProduct(id, name);

以下是javascript代码:

$(document).ready(function () {
    ko.applyBindings(new mfProductViewModel());
});

function markSelected(anchor) {
    // Update the value of the hidden fields with id and Text coming from the "moused over" link.
    $("#selectedProdId").val(anchor.id);
    $("#selectedProdName").val(anchor.innerText);
};

我的目的是点击无序列表中的任何链接,在mfProductViewModel.selectedProducts可观察集合中添加所选产品,并在视图的<div id="selectedProducts">部分显示产品名称。

有没有人使用KnockOut.js来面对这种功能?

非常感谢您分享您的知识。

1 个答案:

答案 0 :(得分:0)

可以选择的可用产品也是一种数据,因此属于ViewModel,而不属于View(HTML文件)。

function mfProductViewModel() {
    // Data
    var self = this;
    self.selectedProducts = ko.observableArray([]);

    self.products = [
        new mfProduct({ MfProductId: '00001', MfProductName: 'Milky Way' }),
        new mfProduct({ MfProductId: '00002', MfProductName: 'Bocadin' }),
        // ...
    ];

    // Operations
    self.addProduct = function(data) {
        // add a copy to allow that the same item is added more than once
        self.selectedProducts.push(new mfProduct(data));
    };

    // ...
};

然后简单地使用knockout渲染列表:

<ul data-bind="foreach: products">
    <li><a href="#" data-bind="text: MfProductName, click: $root.addProduct"></a></li>
</ul>

稍微简化的例子:http://jsfiddle.net/vp9Lqxkp/