将字符串参数传递给点击绑定,同时在 Knockoutjs 中保留默认参数 [英] Pass string parameters into click binding while retaining default params in Knockoutjs

查看:19
本文介绍了将字符串参数传递给点击绑定,同时在 Knockoutjs 中保留默认参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将参数传递给单击时调用的函数,同时保留默认参数.问题出在啤酒花部分.我试图使 remove 功能更干净:

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

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

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

ko.observableArray.fn.countVisible = function(){返回 ko.computed(function(){var items = this();if (items === undefined || items.length === undefined){返回0;}变量可见计数 = 0;for (var index = 0; index < items.length; index++){if (items[index]._destroy != true){可见计数++;}}返回可见计数;}, 这)();};功能跳(数据){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");}功能可发酵(数据){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");}功能酵母(数据){this.name = ko.observable(data.name || "White Wine");}函数 TaskListViewModel() {//数据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([新酵母({})]);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', 酵母: ['Danstar 1', 'Danstar 2']},{category: 'Fermentis', 酵母: ['West Coast', 'American Saison', 'White Wine']},{category: 'White Labs', 酵母: ['White 1', 'White Saison']},]);self.addFermentable = function(){self.fermentables.push(new Fermentable({}))}self.addYeast = function(){self.yeasts.push(新酵母({}));}self.addHop = function(){self.hops.push(new Hop({}));}self.removeFermentable = 函数(可发酵){self.fermentables.destroy(可发酵);}self.removeYeast = 函数(酵母){self.yeasts.destroy(酵母);}self.removeHop = 函数(跳跃){self.hops.destroy(hop);}self.removeItem = 函数(项目,名称){self[name].destroy(item);}self.prepareJSON = function(){对象 = {发酵物:self.fermentables(),啤酒花:self.hops(),酵母:self.yeasts(),}返回对象}self.saveRecipeData = function(){var data_to_send = ko.toJSON(self);var recipe_data = ko.toJSON(self.prepareJSON());alert("这是您要发送的数据(通用 Javascript 对象表示法):

" + recipe_data)$.ajax({网址:http://127.0.0.1:5000/receive-recipe",标题:{内容类型":应用程序/json"},方法:POST",数据类型:json",数据:data_to_send,成功:功能(数据){console.log("成功!保存食谱");}});}}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><头><身体><div class="row"><h2>可发酵物</h2><div data-bind="foreach: 发酵物"><label>名称:</label><input type="text" data-bind="value: name"/><label>数量:</label><input style="width: 45px;"type="number" min="0" data-bind="值:磅"/>磅<input style="width: 55px;"type="number" min="0" data-bind="value: ounces"/>盎司<label>铣削偏好:</label><select data-bind="options: $root.milling_preferences, value: weight_unit"></选择><a href="#" data-bind="点击:$root.removeFermentable,可见:$root.fermentables.countVisible() > 1">删除</a><br><br>

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

<div class="row"><h2 class="">酵母</h2><div data-bind="foreach: 酵母"><span>酵母品牌过滤器:</span><select id="酵母品牌选择"><option value="">-Any-</option><option value="Danstar">Danstar</option><option value="White Labs">White Labs</option><option value="Wyeast">Wyeast</option><option value="-">其他</option></选择><br/><span>酵母品种:</span><select id="yeast-variety-select" style="width:325px" data-bind="value: name"><选项值=-">- </选项><!-- ko foreach: $root.yeast_groups --><optgroup data-bind="attr: {label: category}"><!-- ko foreach: 酵母--><option data-bind="value: $data, text: $data"></option><!--/ko --></optgroup><!--/ko --></选择><a href="#" data-bind="点击:$root.removeYeast,可见:$root.yeasts.countVisible() > 1">删除</a><br><br>

<br><input data-bind="click: addYeast" type="button" value="添加酵母"/>

<div class="row"><h2 class="">Hops</h2><div data-bind='foreach: hops'><label>跳:</label><input type="text" data-bind="value: name" ><label>数量:</label><input type="number" data-bind="value: amount" maxlength="6">盎司时间:<input type="text" data-bind="value: time" >最小使用:<select data-bind="options: $root.hops_uses, value: use"></select><a href="#" data-bind="click: function() { $root.removeItem($data, "hops") },可见:$root.hops.countVisible() > 1">Delete</a><br><br>

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

<p><button data-bind="click: saveRecipeData">保存食谱</button></p>

解决方案

我用这段代码试过了,它奏效了 -

self.removeItem = function(item, name) {name.remove(function(hop){返回 hop.name === item.name;});控制台日志(名称());console.log(self.hops());}

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

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

对于可发酵物酵母来说也是如此.

我建议您为要添加的每一行设置一些唯一的属性,以便它可以成为 self.removeItem 函数内的匹配条件,因为正如我所见,有两个记录可以具有完全相同的数据,这可能导致从数组中删除哪个项目的歧义.

小提琴这里

I'd like to pass arguments in to functions called on click, while retaining the default args. The issue is in the Hops part. I tried to make the remove<this> functions more clean with:

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

and

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

I have tried passing $data, event, "hops" also. I went based on Knockout.js - passing parameters but I want to access the current element (the hop, grain, or yeast I'm deleting) while also giving the string of the array to delete from.

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):

" + 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>

解决方案

I tried with this code and it worked -

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

Also change the binding for deleting like so -

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

And similarly for fermentables and yeasts.

I would suggest you to have some unique property associated with each row that you are adding so that it can be the matching criterion inside of the self.removeItem function, because as I can see, two records can have the exact same data which can cause ambiguity as to which item to remove from the array.

Fiddle here

这篇关于将字符串参数传递给点击绑定,同时在 Knockoutjs 中保留默认参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆