将字符串参数传递给单击绑定,同时保留Knockoutjs中的默认参数

时间:2016-11-09 07:23:09

标签: javascript jquery html knockout.js

我希望将参数传递给click上调用的函数,同时保留默认的args。问题出在Hops部分。我试图通过以下方式使remove<this>函数更加干净:

self.removeItem = function(item, name){
        self[name].destroy(item);
}

<a href="#" data-bind="click: function() { $root.removeItem($data, "hops") }, visible: $root.hops.countVisible() > 1">Delete</a>

我也试过传递$data, event, "hops"。我基于Knockout.js - passing parameters,但我想访问当前元素(我删除的啤酒花,谷物或酵母),同时还提供要删除的数组的字符串。

&#13;
&#13;
ko.observableArray.fn.countVisible = function(){
    return ko.computed(function(){
        var items = this();

        if (items === undefined || items.length === undefined){
            return 0;
        }

        var visibleCount = 0;

        for (var index = 0; index < items.length; index++){
            if (items[index]._destroy != true){
                visibleCount++;
            }
        }

        return visibleCount;
    }, this)();
};

function Hop(data) {
    this.name = ko.observable(data.name || "");
    this.amount = ko.observable(data.amount || "");
    this.time = ko.observable(data.time || "");
    this.use = ko.observable(data.use || "Boil");
}

function Fermentable(data) {
    this.name = ko.observable(data.name || "");
    this.pounds = ko.observable(data.pounds || "");
    this.ounces = ko.observable(data.ounces || "");
    this.weight_unit = ko.observable(data.weight_unit || "oz");
    this.milling_preference = ko.observable(data.milling_preference || "Milled");
}

function Yeast(data){
    this.name = ko.observable(data.name || "White Wine");
}

function TaskListViewModel() {
    // Data
    var self = this;

    self.recipe_name = ko.observable("");
    self.hops = ko.observableArray([new Hop({}), new Hop({})]);
    self.fermentables = ko.observableArray([new Fermentable({name: 'test'}), new Fermentable({})]);
    self.yeasts = ko.observableArray([new Yeast({})]);
    self.hops_uses = ko.observableArray(['Boil', 'Dry Hop']);
    self.weight_units = ko.observableArray(['oz', 'lb']);
    self.milling_preferences = ko.observableArray(['Milled', 'Unmilled']);
    self.yeast_groups = ko.observableArray(
        [
            {category: 'Danstar', yeasts: ['Danstar 1', 'Danstar 2']},
            {category: 'Fermentis', yeasts: ['West Coast', 'American Saison', 'White Wine']},
            {category: 'White Labs', yeasts: ['White 1', 'White Saison']},
        ]
    );

    self.addFermentable = function(){
        self.fermentables.push(new Fermentable({}))
    }

    self.addYeast = function(){
        self.yeasts.push(new Yeast({}));
    }

    self.addHop = function(){
        self.hops.push(new Hop({}));
    }

    self.removeFermentable = function(fermentable){
        self.fermentables.destroy(fermentable);
    }

    self.removeYeast = function(yeast){
        self.yeasts.destroy(yeast);
    }

    self.removeHop = function(hop){
        self.hops.destroy(hop);
    }

    self.removeItem = function(item, name){
        self[name].destroy(item);
    }

    self.prepareJSON = function(){
        object = {
            fermentables: self.fermentables(),
            hops: self.hops(),
            yeasts: self.yeasts(),
        }
        return object
    }

    self.saveRecipeData = function(){
        var data_to_send = ko.toJSON(self);
        var recipe_data = ko.toJSON(self.prepareJSON());
        alert("This is the data you're sending (universal Javascript object notation):\n\n" + recipe_data)
        $.ajax({
            url: "http://127.0.0.1:5000/receive-recipe",
            headers: {
                "Content-Type": "application/json"
            },
            method: "POST",
            dataType: "json",
            data: data_to_send,
            success: function(data){
                console.log("Success! Saved the recipe");
            }
        });
    }


}
ko.applyBindings(new TaskListViewModel());
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>

<head>

</head>

<body>
    <div class="row">
        <h2>Fermentables</h2>
        <div data-bind="foreach: fermentables">
            <label>Name:</label>
            <input type="text" data-bind="value: name"/>
            <label>Amount:</label>
            <input style="width: 45px;" type="number" min="0" data-bind="value: pounds"/> lb
            <input style="width: 55px;" type="number" min="0" data-bind="value: ounces"/> oz
            <label>Milling preference: </label>
            <select data-bind="options: $root.milling_preferences, value: weight_unit">
            </select>
            <a href="#" data-bind="click: $root.removeFermentable, visible: $root.fermentables.countVisible() > 1">
                Delete
            </a>
            <br><br>
        </div>

        <input data-bind="click: addFermentable" type="button" value="Add Fermentable" />
    </div>

    <div class="row">
        <h2 class="">Yeast</h2>
        <div data-bind="foreach: yeasts">
            <span>Yeast Brand Filter:</span>
            <select id="yeast-brand-select">
                <option value="">-Any-</option>
                <option value="Danstar">Danstar</option>
                <option value="White Labs">White Labs</option>
                <option value="Wyeast">Wyeast</option>
                <option value="-">Others</option>
            </select>
            <br/>
            <span>Yeast Variety:</span>
            <select id="yeast-variety-select" style="width:325px" data-bind="value: name">
                <option value="-"> - </option>
                <!-- ko foreach: $root.yeast_groups -->
                    <optgroup data-bind="attr: {label: category}">
                        <!-- ko foreach: yeasts -->
                            <option data-bind="value: $data, text: $data"></option>
                        <!-- /ko -->
                    </optgroup>
                <!-- /ko -->
            </select>
            <a href="#" data-bind="click: $root.removeYeast, visible: $root.yeasts.countVisible() > 1">Delete</a>
            <br><br>
        </div>
        <br>
        <input data-bind="click: addYeast" type="button" value="Add Yeast"/>
    </div>

    <div class="row">
        <h2 class="">Hops</h2>
        <div data-bind='foreach: hops'>
            <label>Hop:</label> <input type="text" data-bind="value: name" >
            <label>Amount:</label>
            <input type="number" data-bind="value: amount" maxlength="6"> oz

            Time: <input type="text" data-bind="value: time" >
            Min.
            Use:  <select data-bind="options: $root.hops_uses, value: use"></select>

            <a href="#" data-bind="click: function() { $root.removeItem($data, "hops") }, visible: $root.hops.countVisible() > 1">Delete</a>

            <br><br>
        </div>

        <br>

        <input data-bind="click: addHop" type="button" value="Add Hop" />
    </div>

    <p>
        <button data-bind="click: saveRecipeData">Save recipe</button>
    </p>
</body>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:2)

我尝试使用此代码并且有效 -

<div class="nav">
  <span id="title">Title</span>
  <div class="dropdown">
    <span class="dropbutton">☰</span>
    <div class="dropdown-content">
      <a href="#">Link 1</a>
      <a href="#">Link 2</a>
      <a href="#">Link 3</a>
    </div>
  </div>

</div>

同样更改绑定以进行删除 -

self.removeItem = function(item, name) {    
    name.remove(function(hop){
        return hop.name === item.name;
    });
    console.log(name());
    console.log(self.hops());   
}

同样适用于 fermentables 酵母

我建议你有一些与你要添加的每一行相关联的唯一属性,以便它可以作为<a href="#" data-bind="click: function() { $root.removeItem($data, $root.hops) }, visible: $root.hops.countVisible() > 0">Delete</a> 函数内部的匹配条件,因为我可以看到,两条记录可以准确无误相同的数据可能会导致从阵列中删除哪个项目的含糊不清。

小提琴here