【问题标题】:Pass string parameters into click binding while retaining default params in Knockoutjs将字符串参数传递给点击绑定,同时在 Knockoutjs 中保留默认参数
【发布时间】:2016-11-09 07:23:09
【问题描述】:

我想将参数传递给单击时调用的函数,同时保留默认参数。问题在于啤酒花部分。我试图使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,但我想访问当前元素(我正在删除的啤酒花、谷物或酵母),同时还提供要从中删除的数组字符串。

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());
<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>

【问题讨论】:

    标签: javascript jquery html knockout.js


    【解决方案1】:

    我尝试了这段代码,它成功了 -

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

    也像这样更改删除的绑定 -

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

    fermentablesyeasts 也是如此。

    我建议您为要添加的每一行关联一些唯一属性,以便它可以成为 self.removeItem 函数内部的匹配标准,因为正如我所见,两条记录可以具有完全相同的数据这可能会导致从数组中删除哪个项目不明确。

    小提琴here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-19
      • 2016-03-16
      • 1970-01-01
      • 1970-01-01
      • 2011-05-12
      • 2011-06-29
      相关资源
      最近更新 更多