淘汰赛 arrayfirst 没有按预期工作 [英] knockout arrayfirst not working as expected

查看:14
本文介绍了淘汰赛 arrayfirst 没有按预期工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一堆敲除代码和绑定的小提琴.我有一个绑定来检查 observablearray 中的一个项目,它似乎总是返回 true,无论我输入什么值.将光标放在最后一行的最后一个输入中并跳出.它将添加一个新行.现在在第一个输入中键入一个值并跳出.它应该检查现有的 observablearray 并在它存在时返回 true 或 false.小提琴:https://jsfiddle.net/mf1wona9/6/

HTML:

<头><tr><th>编号</th><th>兄弟代码</th><th width="36%">描述</th><th width="15%">零售</th><th>奖品数量</th><th>命令</th><th>消除</th></tr></thead><tbody data-bind="foreach: items"><tr><td><div data-bind="if: ($index() === $parent.items().length-1)"><input data-bind="value: itemNo, hasFocus: $parent.invalidItem(), 选中: $parent.invalidItem(), event: { blur: $parent.checkItemNo }, attr: { name: 'brochureitems[' + $index() + '].itemNo', id: 'brochureItems_' +$index() + '__itemNo' }, validationOptions: { errorElementClass: 'input-validation-error' }" class="form-control item-id"/></div><div data-bind="ifnot: ($index() === $parent.items().length-1)"><input data-bind="value: itemNo, attr: { name: '小册子项目[' + $index() + '].itemNo', id: 'brochureItems_' + $index() + '__itemNo' }, validationOptions: { errorElementClass: 'input-validation-error' }" class="form-control item-ID" readonly="readonly" tabindex="-1"/></div></td><td><div data-bind="if: (brocCode.length < 1)"><input data-bind="value: brocCode, insertPress: $index, attr: { name: 'brochureitems[' + $index() + '].brocCode', id: 'brochureItems_' + $index() + '__brocCode' }, validationOptions: { errorElementClass: 'input-validation-error' }" class="form-control"/>

<div data-bind="if: (brocCode.length > 0)"><input data-bind="value: brocCode, insertPress: $index, attr: { name: 'brochureitems[' + $index() + '].brocCode', id: 'brochureItems_' + $index() + '__brocCode' }, validationOptions: { errorElementClass: 'input-validation-error' }" class="form-control" readonly="readonly" tabindex="-1"/>

</td><td class="item-desc"><input data-bind="value: itemDesc, attr: { name: 'brochureitems[' + $index() + '].itemDesc', id: 'brochureItems_' + $index() + '__itemDesc' }, validationOptions: { errorElementClass: 'input-validation-error' }" class="form-control" readonly="readonly" tabindex="-1"/></td><td class="item-retail"><div class="input-group"><div class="input-group-addon">$</div><div data-bind="if: ($index() === ($parent.items().length - 1))"><input data-bind="value:retail, valueUpdate:'afterkeydown', attr: { name: 'brochureitems[' + $index() + '].retail', id: 'brochureItems_' + $index() + '__retail' }, validationOptions: { errorElementClass: 'input-validation-error' }, style: { backgroundColor: retail == 0 ? '#FFFCCE' : '#ffffff'}" class="form-control"/></div><div data-bind="if: ($index() < ($parent.items().length - 1))"><input data-bind="value:retail, valueUpdate:'afterkeydown', 钱: 零售, attr: { name: 'brochureitems[' + $index() + '].retail', id: 'brochureItems_' + $index() + '__retail' }, validationOptions: { errorElementClass: 'input-验证错误'},样式:{backgroundColor:retail == 0 ?'#FFFCCE':'#ffffff'}" class="form-control" readonly="readonly" tabindex="-1"/></div>

</td><td><div><input data-bind="value: PrizeNum, valueUpdate: 'afterkeydown', attr: { name: 'brochureitems[' + $index() + '].prizeNum', id: 'brochureItems_' + $index() + '__prizeNum' }, validationOptions: { errorElementClass: 'input-validation-error' }, style: { backgroundColor: PrizeNum == 0 ? '#FFFCCE' : '#ffffff'}" class="form-control"/></div></td><td><div data-bind="if: ($index() === ($parent.items().length - 1))"><input data-bind="value: itemOrder, valueUpdate: 'afterkeydown', enterPress: 'addRow', attr: { name: 'brochureitems[' + $index() + '].itemOrder', id: 'brochureItems_' + $index() + '__itemOrder' }, validationOptions: { errorElementClass:'input-validation-error' }, style: { backgroundColor: itemOrder == 0 ? '#FFFCCE' : '#ffffff'}" class="form-control"/></div><div data-bind="if: ($index() < ($parent.items().length - 1))"><input data-bind="value: itemOrder, valueUpdate: 'afterkeydown', attr: { name: 'brochureitems[' + $index() + '].itemOrder', id: 'brochureItems_' + $index() + '__itemOrder' }, validationOptions: { errorElementClass: 'input-validation-error'}, style: { backgroundColor: itemOrder == 0 ? '#FFFCCE' : '#ffffff'}" class="form-control"/></div></td><td class="remove"><span class="glyphicon glyphicon-remove removeRow" data-bind="click: $parent.removeItem"></span></td></tr></tbody>

淘汰赛:

var listOfItems;ko.validation.rules.pattern.message = '无效.';ko.validation.init({注册扩展器:真,messagesOnModified: 真,插入消息:真,parseInputAttributes: 真,消息模板:空,装饰输入元素:真,}, 真的);(功能(){var toMoney = 函数(数量){if(num != null && num != "") {num = parseFloat(num);返回 (num.toFixed(2).replace(/(d)(?=(d{3})+.)/g, '$1,') );} 别的 {返回 "";}};var handler = function(element, valueAccessor, allBindings){var $el = $(元素);var方法;//给我们真实的值,如果它是一个计算出的 observable 或者不是var valueUnwrapped = ko.unwrap( valueAccessor() );if($el.is(':input')){方法 = 'val';} 别的 {方法 = '文本';}返回 $el[method]( toMoney( valueUnwrapped ) );};ko.bindingHandlers.money = {更新:处理程序};})();var itemModel = 函数(数据){var self = this;self.invalidItem = ko.observable(true);self.itemNo = ko.observable(data ? data.itemNo : '').extend( {必需的: {参数:真实,消息:需要项目编号."}});self.brocCode = ko.observable(data ? data.brocCode : '').extend( {必需的: {参数:真实,消息:需要兄弟代码."}});self.itemDesc = ko.observable(data ? data.itemDesc : '').extend( {必需的: {参数:真实,消息:需要项目描述."}});self.retail = ko.observable(data ? data.retail : '').extend( {必需的: {参数:真实,消息:需要零售."}}).extend({数字: 2});self.prizeNum = ko.observable(data ? data.prizeNum : '').extend( {必需的: {参数:真实,消息:需要奖品编号."}});self.itemOrder = ko.observable(data ? data.itemOrder : '').extend( {必需的: {参数:真实,消息:需要物品订单."}});}var itemsModel = function(items) {var self = this;self.items = ko.mapping.fromJSON(items);self.invalidItem = ko.observable(true);self.checkItemNo = 函数(数据){console.log("失去焦点 - " + self.invalidItem());var itemNo = $.trim(data.itemNo());console.log(itemNo);如果(项目号!="){var item = "";item = "融合";控制台日志(项目);如果(项目!="){var match = ko.utils.arrayFirst(self.items(), function(newItem) {返回 itemNo === newItem.itemNo();}).编号();console.log("匹配:" + 匹配);如果(!匹配){data.itemDesc(item);} else {//项目已经输入console.log("项目已输入");data.invalidItem(true);setTimeout(function() { data.invalidItem(true); }, 1);//data.itemDesc("");}} else {//无效的项目#console.log("无效项目");data.invalidItem(true);setTimeout(function() { data.invalidItem(true); }, 1);data.itemDesc("");}}}self.submit = function() {//self.showErrors(true);如果 (viewModel.errors().length === 0) {console.log('谢谢你.');$("#brochureForm").submit();}别的 {console.log('请检查您提交的内容.');viewModel.errors.showAllMessages();$(".input-validation-error").first().focus();}}self.addLine = function() {var iModel = new itemModel();iModel.invalidItem(true);self.invalidItem(true);console.log("添加新行;它是:" + self.invalidItem());self.items.push( iModel );//setTimeout(function() { self.invalidItem(true); }, 1);};self.insertLine = 函数(索引){self.items.splice(index, 0, new itemModel());};self.removeItem = function(item) {self.items.remove(item);};self.errors = ko.validation.group(self.items, { deep: true, live: true });self.validate = function() {self.errors.showAllMessages();}};var 利润代码 = 函数(代码,描述,名称){this.code = 代码;this.desc = desc;this.name = 名称;};var codeModel = 函数(代码){var self = this;self.availableProfitCodes = ko.observableArray([])self.codes = ko.observableArray(codes);}var 利润项目模型 = 函数(项目){var self = this;self.items = ko.observableArray(items);}var组合=(函数(){函数组合VM(){this.codes = ko.observable(codeModel);this.items = ko.observable(利润项目模型);this.availableProfitCodes = codeModel.availableProfitCodes;}返回组合VM;})();ko.bindingHandlers.enterPress = {初始化:函数(元素,valueAccessor,allBindingsAccessor,viewModel,bindingContext){var allBindings = allBindingsAccessor();element.addEventListener('keydown', function (event) {var keyCode = (event.which ? event.which : event.keyCode);if (keyCode === 13 || (!event.shiftKey && keyCode === 9)) {event.preventDefault();//bindingContext.$root.invalidItem(false);bindingContext.$root.addLine();返回假;}返回真;});}};ko.bindingHandlers.insertPress = {初始化:函数(元素,valueAccessor,allBindingsAccessor,viewModel,bindingContext){var allBindings = allBindingsAccessor();element.addEventListener('keydown', function (event) {var keyCode = (event.which ? event.which : event.keyCode);如果(keyCode === 45){event.preventDefault();bindingContext.$root.insertLine(ko.unwrap(valueAccessor()));返回假;}返回真;});}};ko.bindingHandlers.selected = {更新:函数(元素,valueAccessor,allBindingsAccessor,viewModel,bindingContext){var selected = ko.utils.unwrapObservable(valueAccessor());如果(选择) element.select();}};函数 GetItems() {var itemsJSON = '[{"brochureId":1,"itemNo":"1000","brocCode":"1000","itemDesc":"Bicycle","re​​tail":13.5,"prizeNum":1,"itemOrder":1},{"brochureId":1,"itemNo":"1100","brocCode":"1100","itemDesc":"Front Wheel","re​​tail":35,"prizeNum":2,"itemOrder":2},{"brochureId":1,"itemNo":"1120","brocCode":"1120","itemDesc":"Spokes","re​​tail":12.5,"prizeNum":3,"itemOrder":3},{"brochureId":1,"itemNo":"1150","brocCode":"1150","itemDesc":"Front Hub","re​​tail":5,"prizeNum":4,"itemOrder":4},{"brochureId":1,"itemNo":"1151","brocCode":"1151","itemDesc":"Axle Front Wheel","re​​tail":14,"prizeNum":5, "itemOrder":5},{"brochureId":1,"itemNo":"120","brocCode":"120","itemDesc":"Loudspeaker, Black, 120W","re​​tail":12.5,"prizeNum":6, "itemOrder":6},{"brochureId":1,"itemNo":"125","brocCode":"125","itemDesc":"Socket Back","re​​tail":10, "prizeNum":7, "itemOrder":7}]';var viewModel = new itemsModel(itemsJSON);ko.applyBindings(viewModel, $("#brochureItems")[0]);}$(document).ready(function () {获取项目();});

解决方案

新项目是可观察数组的一部分.要检查它是否与某些other 项目匹配,您需要确保没有将它与自身进行比较:

var match = ko.utils.arrayFirst(self.items(), function(newItem) {返回数据 !== newItem &&itemNo === newItem.itemNo();});

I have a fiddle with a bunch of knockout code and bindings. I have one binding that checks for an item in an observablearray and it seems to be always returning true, no matter what value I type in. Put your cursor in the last input on the last row and tab out. It will add a new row. Now type a value into the first input and tab out. It is supposed to check the existing observablearray and return true or false if it exists. Fiddle: https://jsfiddle.net/mf1wona9/6/

HTML:

<table class="table table-bordered table-striped" id="brochureItems">
<thead>
    <tr>
        <th>
            Item No
        </th>
        <th>
            Bro Code
        </th>
        <th width="36%">
            Desc
        </th>
        <th width="15%">
            Retail
        </th>
        <th>
            Prize Cnt
        </th>
        <th>
            Order
        </th>
        <th>
            Remove
        </th>
    </tr>
</thead>
<tbody data-bind="foreach: items">
    <tr>
        <td>
            <div data-bind="if: ($index() === $parent.items().length-1)"><input data-bind="value: itemNo, hasFocus: $parent.invalidItem(), selected: $parent.invalidItem(), event: { blur: $parent.checkItemNo }, attr: { name: 'brochureitems[' + $index() + '].itemNo', id: 'brochureItems_' + $index() + '__itemNo' }, validationOptions: { errorElementClass: 'input-validation-error' }" class="form-control item-id" /></div>
            <div data-bind="ifnot: ($index() === $parent.items().length-1)"><input data-bind="value: itemNo, attr: { name: 'brochureitems[' + $index() + '].itemNo', id: 'brochureItems_' + $index() + '__itemNo' }, validationOptions: { errorElementClass: 'input-validation-error' }" class="form-control item-ID" readonly="readonly" tabindex="-1" /></div>
        </td>
        <td>
            <div data-bind="if: (brocCode.length < 1)">
                <input data-bind="value: brocCode, insertPress: $index, attr: { name: 'brochureitems[' + $index() + '].brocCode', id: 'brochureItems_' + $index() + '__brocCode' }, validationOptions: { errorElementClass: 'input-validation-error' }" class="form-control" />
            </div>
            <div data-bind="if: (brocCode.length > 0)">
                <input data-bind="value: brocCode, insertPress: $index, attr: { name: 'brochureitems[' + $index() + '].brocCode', id: 'brochureItems_' + $index() + '__brocCode' }, validationOptions: { errorElementClass: 'input-validation-error' }" class="form-control" readonly="readonly" tabindex="-1" />
            </div>
        </td>
        <td class="item-desc">
            <input data-bind="value: itemDesc, attr: { name: 'brochureitems[' + $index() + '].itemDesc', id: 'brochureItems_' + $index() + '__itemDesc' }, validationOptions: { errorElementClass: 'input-validation-error' }" class="form-control" readonly="readonly" tabindex="-1" />
        </td>
        <td class="item-retail">
            <div class="input-group">
                <div class="input-group-addon">$</div>
                <div data-bind="if: ($index() === ($parent.items().length - 1))"><input data-bind="value: retail, valueUpdate: 'afterkeydown', attr: { name: 'brochureitems[' + $index() + '].retail', id: 'brochureItems_' + $index() + '__retail' }, validationOptions: { errorElementClass: 'input-validation-error' }, style: { backgroundColor: retail == 0 ? '#FFFCCE' : '#ffffff'}" class="form-control" /></div>
                <div data-bind="if: ($index() < ($parent.items().length - 1))"><input data-bind="value: retail, valueUpdate: 'afterkeydown', money: retail, attr: { name: 'brochureitems[' + $index() + '].retail', id: 'brochureItems_' + $index() + '__retail' }, validationOptions: { errorElementClass: 'input-validation-error' }, style: { backgroundColor: retail == 0 ? '#FFFCCE' : '#ffffff'}" class="form-control" readonly="readonly" tabindex="-1" /></div>
            </div>
        </td>
        <td>
            <div><input data-bind="value: prizeNum, valueUpdate: 'afterkeydown', attr: { name: 'brochureitems[' + $index() + '].prizeNum', id: 'brochureItems_' + $index() + '__prizeNum' }, validationOptions: { errorElementClass: 'input-validation-error' }, style: { backgroundColor: prizeNum == 0 ? '#FFFCCE' : '#ffffff'}" class="form-control" /></div>
        </td>
        <td>
            <div data-bind="if: ($index() === ($parent.items().length - 1))"><input data-bind="value: itemOrder, valueUpdate: 'afterkeydown', enterPress: 'addRow', attr: { name: 'brochureitems[' + $index() + '].itemOrder', id: 'brochureItems_' + $index() + '__itemOrder' }, validationOptions: { errorElementClass: 'input-validation-error' }, style: { backgroundColor: itemOrder == 0 ? '#FFFCCE' : '#ffffff'}" class="form-control" /></div>
            <div data-bind="if: ($index() < ($parent.items().length - 1))"><input data-bind="value: itemOrder, valueUpdate: 'afterkeydown', attr: { name: 'brochureitems[' + $index() + '].itemOrder', id: 'brochureItems_' + $index() + '__itemOrder' }, validationOptions: { errorElementClass: 'input-validation-error' }, style: { backgroundColor: itemOrder == 0 ? '#FFFCCE' : '#ffffff'}" class="form-control" /></div>
        </td>
        <td class="remove"><span class="glyphicon glyphicon-remove removeRow" data-bind="click: $parent.removeItem"></span></td>

    </tr>
</tbody>

Knockout:

var listOfItems;

ko.validation.rules.pattern.message = 'Invalid.';
    ko.validation.init({
        registerExtenders: true,
        messagesOnModified: true,
        insertMessages: true,
        parseInputAttributes: true,
        messageTemplate: null,
        decorateInputElement: true,
    }, true);

    (function(){

        var toMoney = function(num){
            if(num != null && num != "") {
                num = parseFloat(num);
                return (num.toFixed(2).replace(/(d)(?=(d{3})+.)/g, '$1,') );
            } else {
                return "";
            }
        };

        var handler = function(element, valueAccessor, allBindings){
            var $el = $(element);
            var method;

            // Gives us the real value if it is a computed observable or not
            var valueUnwrapped = ko.unwrap( valueAccessor() );

            if($el.is(':input')){
                method = 'val';
            } else {
                method = 'text';
            }
            return $el[method]( toMoney( valueUnwrapped ) );
        };

        ko.bindingHandlers.money = {
            update: handler
        };
    })();

    var itemModel = function (data) {
        var self = this;
        self.invalidItem = ko.observable(true);
        self.itemNo = ko.observable(data ? data.itemNo : '').extend( {
            required: {
                params: true,
                message: "Item no. required."
            }
        });
        self.brocCode = ko.observable(data ? data.brocCode : '').extend( {
            required: {
                params: true,
                message: "Bro code required."
            }
        });
        self.itemDesc = ko.observable(data ? data.itemDesc : '').extend( {
            required: {
                params: true,
                message: "Item desc required."
            }
        });
        self.retail = ko.observable(data ? data.retail : '').extend( {
            required: {
                params: true,
                message: "Retail required."
            }
        })
        .extend({numeric: 2});
        self.prizeNum = ko.observable(data ? data.prizeNum : '').extend( {
            required: {
                params: true,
                message: "Prize num required."
            }
        });
        self.itemOrder = ko.observable(data ? data.itemOrder : '').extend( {
            required: {
                params: true,
                message: "Item order required."
            }
        });
    }

    var itemsModel = function(items) {
        var self = this;
        self.items = ko.mapping.fromJSON(items);

        self.invalidItem = ko.observable(true);

        self.checkItemNo = function(data) {
            console.log("lost focus - " + self.invalidItem());
            var itemNo = $.trim(data.itemNo());
            console.log(itemNo);
            if (itemNo != "") {
                var item = "";
                item = "Fusion";
                console.log(item);
                if(item != "") {
                    var match = ko.utils.arrayFirst(self.items(), function(newItem) {
                        return itemNo === newItem.itemNo();
                    }).itemNo();
                    console.log("match: " + match);
                    if (!match) {
                        data.itemDesc(item);
                    } else { // item already entered
                        console.log("item already entered");
                      data.invalidItem(true);
                      setTimeout(function() { data.invalidItem(true); }, 1);
                      //data.itemDesc("");
                    }
                } else { // invalid item #
                    console.log("invalid item");
                    data.invalidItem(true);
                    setTimeout(function() { data.invalidItem(true); }, 1);
                    data.itemDesc("");
                }
            }
        }

        self.submit = function() {
            //self.showErrors(true);
            if (viewModel.errors().length === 0) {
                console.log('Thank you.');
                $("#brochureForm").submit();
            }
            else {
                console.log('Please check your submission.');
                viewModel.errors.showAllMessages();
                $(".input-validation-error").first().focus();
            }
        }

        self.addLine = function() {
            var iModel = new itemModel();
            iModel.invalidItem(true);
            self.invalidItem(true);
            console.log("adding new line; it is: " + self.invalidItem());
            self.items.push( iModel );
            //setTimeout(function() { self.invalidItem(true); }, 1);
        };

        self.insertLine = function(index) {
            self.items.splice(index, 0, new itemModel() );
        };

        self.removeItem = function(item) {
            self.items.remove(item);
        };

        self.errors = ko.validation.group(self.items, { deep: true, live: true });

        self.validate = function() {
            self.errors.showAllMessages();
        }
    };

    var profitCode = function(code, desc, name) {
        this.code = code;
        this.desc = desc;
        this.name = name;
    };

    var codeModel = function(codes) {
        var self = this;
        self.availableProfitCodes = ko.observableArray([])
        self.codes = ko.observableArray(codes);
    }

    var profitItemsModel = function(items) {
        var self = this;
        self.items = ko.observableArray(items);
    }

    var combined = (function () {
        function combinedVM() {
            this.codes = ko.observable(codeModel);
            this.items = ko.observable(profitItemsModel);
            this.availableProfitCodes = codeModel.availableProfitCodes;
        }
        return combinedVM;
    })();

    ko.bindingHandlers.enterPress = {
        init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
            var allBindings = allBindingsAccessor();
            element.addEventListener('keydown', function (event) {
                var keyCode = (event.which ? event.which : event.keyCode);
                if (keyCode === 13 || (!event.shiftKey && keyCode === 9)) {
                    event.preventDefault();
                    //bindingContext.$root.invalidItem(false);
                    bindingContext.$root.addLine();
                    return false;
                }
                return true;
            });
        }
    };

        ko.bindingHandlers.insertPress = {
            init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
                var allBindings = allBindingsAccessor();
                element.addEventListener('keydown', function (event) {
                    var keyCode = (event.which ? event.which : event.keyCode);
                    if (keyCode === 45) {
                        event.preventDefault();
                        bindingContext.$root.insertLine(ko.unwrap(valueAccessor()));
                        return false;
                    }
                    return true;
                });
            }
        };

        ko.bindingHandlers.selected = {
            update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
                var selected = ko.utils.unwrapObservable(valueAccessor());
                if (selected) element.select();
            }
        };        

        function GetItems() {
    var itemsJSON =  '[{"brochureId":1,"itemNo":"1000","brocCode":"1000","itemDesc":"Bicycle","retail":13.5, "prizeNum":1, "itemOrder":1},{"brochureId":1,"itemNo":"1100","brocCode":"1100","itemDesc":"Front Wheel","retail":35, "prizeNum":2, "itemOrder":2},{"brochureId":1,"itemNo":"1120","brocCode":"1120","itemDesc":"Spokes","retail":12.5, "prizeNum":3, "itemOrder":3},{"brochureId":1,"itemNo":"1150","brocCode":"1150","itemDesc":"Front Hub","retail":5, "prizeNum":4, "itemOrder":4},{"brochureId":1,"itemNo":"1151","brocCode":"1151","itemDesc":"Axle Front Wheel","retail":14, "prizeNum":5, "itemOrder":5},{"brochureId":1,"itemNo":"120","brocCode":"120","itemDesc":"Loudspeaker, Black, 120W","retail":12.5, "prizeNum":6, "itemOrder":6},{"brochureId":1,"itemNo":"125","brocCode":"125","itemDesc":"Socket Back","retail":10, "prizeNum":7, "itemOrder":7}]';
    var viewModel = new itemsModel(itemsJSON);
    ko.applyBindings(viewModel, $("#brochureItems")[0]);
  }

$(document).ready(function () {
    GetItems();
});

解决方案

The new item is part of the observable array. To check whether it matches some other item, you need to ensure that you are not comparing it to itself:

var match = ko.utils.arrayFirst(self.items(), function(newItem) {
    return data !== newItem && itemNo === newItem.itemNo();
});

这篇关于淘汰赛 arrayfirst 没有按预期工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆