可观察对象的订阅函数不能正常工作

subscribe function for observable is not working proper

本文关键字:常工作 工作 不能 函数 对象 观察      更新时间:2023-09-26

我以前在这里发布并解决了我的问题,但现在当我试图把这个解决方案放在我原来的应用程序我面临的困难,再次下拉菜单不工作,因为他们在测试页面工作,这是我的代码

这是我之前的问题

            <table class="ListViewtable-minimal grid-100 mobile-grid-100">
            <thead>
                <tr>
                    <th>S. No.</th>
                    <th>Action</th>
                    <th>Code</th>
                    <th>Product</th>
                    <th>Quantity</th>
                    <th>Offers</th>
                    <th>Stock Quantity</th>
                    <th>Packing</th>
                    <th>Rate</th>
                    <th>Total Price</th>                        
                </tr>
            </thead>
            <tbody data-bind='foreach: {data: details,beforeRemove: hideRow,afterAdd: showRow}'>
                <tr>
                    <td><span data-bind='text : $index() + 1'></span> </td>
                    <td><a href="#" data-bind='click: remove'> <img src="../../Assets/img/delete.png" alt="x" /></a> </td>
                    <td><input type="text" data-bind='value: ProductCode' class="txtbx" style="width:100px;"/></td>
                    <td>
                        <input type="hidden" data-bind='value: ID' /> 
                        <select data-bind="options: Products, optionsText: 'Name',optionsValue: 'ID', value: ProductID, optionsCaption: '-'" />
                    </td>
                    <td><input type="text" data-bind='value: Quantity' class="txtbx" style="width:50px;"/></td>
                    <td data-bind="if: ProductID">
                        <select data-bind="options: ProductOffers, optionsText: 'Name',optionsValue: 'ID', value: ProductOfferID, optionsCaption: '-'" />
                    </td>
                    <td><input type="text" data-bind='value: StockQuantity' class="txtbx" style="width:50px;"/> </td>
                    <td><input type="text" data-bind='value: ProductPacking' class="txtbx" style="width:50px;"/> </td>
                    <td><input type="text" data-bind='value: ProductRate' class="txtbx" style="width:80px;"/> </td>
                    <td><input type="text" data-bind='value: TotalPrice' class="txtbx" style="width:120px;"/> </td>
                </tr>
            </tbody>
            <tfoot>
                <tr>
                    <td colspan="2">Totals</td>
                    <td colspan="2"></td>
                    <td data-bind='text: totalQuantity'></td>
                    <td></td>
                    <td></td>
                    <td></td>
                    <td></td>
                    <td></td>
                </tr>
            </tfoot>
        </table>
    </div>
</div>
<div>
    <button runat="server" id="btnAddService" type="submit" class="fleft" data-bind="click: add" >Add New</button>
    <button runat="server" id="btnSaveTop" data-bind="click: save" type="submit" class="fright">Save</button>
    <asp:Button ID="btnBackTop" runat="server" Text="Back"  UseSubmitBehavior="false" CssClass="fright"/>
</div>
<script type="text/javascript">
    this.showRow = function (element) {
        if (element.nodeType === 1) {
            $(element).hide().fadeIn('fast');
        }
    };
    this.hideRow = function (element) {
        if (element.nodeType === 1) {
            $(element).fadeOut(function () { $(element).remove(); });
        }
    };
    function isNumber(n) {
        if (typeof n != "undefined") {
            return !isNaN(parseFloat(n)) && isFinite(n);
        }
        else {
            return false;
        }
    }
    function showMessage(msg) {
        //msg.d contains the success status
        if (typeof (msg) != "undefined" && msg != null && msg.d != null && msg.d.length == 0) {
            //success message here
            setTimeout("window.location = 'index.aspx?ID=" + viewModel.MasterID + "';", 1500);
        }
        else {
            //Error Message Here
        }
    }
    function Product(id, name) {
        this.ID = id;
        this.Name = name;
    }
    //Constructor
    function Details(o) {
        var self = this;
        if (typeof o != "undefined") {
            alert("Constructor called, filled from DB");
            self.ID = ko.observable(o.ID);
            self.ProductCode = ko.observable(o.ProductCode);
            self.Products = ko.observableArray(<%= LoadProducts() %>),
            self.ProductOffers = ko.observableArray(GetProductOffers(self.ProductID))
            self.ProductID = ko.observable(o.ProductID).extend({ numeric: 0 });
            self.ProductOfferID = ko.observable(o.ProductOfferID).extend({ numeric: 0 });
            self.Quantity = ko.observable(o.Quantity).extend({ numeric: 0 });
            self.StockQuantity = ko.observable(o.StockQuantity).extend({ numeric: 0 });
            self.ProductPacking = ko.observable(o.ProductPacking).extend({ numeric: 0 });
            self.ProductRate = ko.observable(o.ProductRate).extend({ numeric: 0 });
            self.TotalPrice = ko.observable(o.TotalPrice).extend({ numeric: 0 });
            self.remove = function (data) {
                if (confirm('This record will be deleted from the source, Are you sure ?')) {
                    //Data is deleted via ajax
                }
            }
        }
        else {
            alert("Constructor called");
            self.ID = ko.observable('0');
            self.ProductCode = ko.observable('');
            self.Products = ko.observableArray(<%= LoadProducts() %>),
            self.ProductOffers = ko.observableArray([])
            self.ProductID = ko.observable('0').extend({ numeric: 0 });
            self.ProductOfferID = ko.observable('0').extend({ numeric: 0 });
            self.Quantity = ko.observable('0').extend({ numeric: 0 });
            self.StockQuantity = ko.observable('1').extend({ numeric: 0 });
            self.ProductPacking = ko.observable('0').extend({ numeric: 0 });
            self.ProductRate = ko.observable('0').extend({ numeric: 0 });
            self.TotalPrice = ko.observable('0').extend({ numeric: 0 });
            self.remove = function (data) {
                if (confirm('Are you sure you want to delete this record ?'))
                    viewModel.details.remove(this);
            }
        }
    }
    //Building ViewModel
    var viewModel = {
        MasterID: 0,
        ProductID: ko.observable('0'),
        details: ko.observableArray([]),
        add: function () {
            this.details.push(new Details());
        },
        load: function (data, MasterID) {
            this.MasterID = MasterID;
            if (data.length == 0) {
                var totalRows = jQuery(".hfNumberOfRows").val();
                if (totalRows != 0) {
                    for (var i = 0; i < totalRows; i++) {
                        this.details.push(new Details());
                    }
                }
                else {
                    this.details.push(new Details());
                }
            }
            else {
                for (i = 0; i < data.length; i++) {
                    this.details.push(new Details(data[i]));
                }
            }
        },
        save: function () {
        }
    }
    viewModel.ProductID.subscribe(function (newValue) {
        viewModel.ProductOffers.removeAll();
        alert(newValue);
        if (newValue) {
            var productOffers = GetProductOffers(newValue);
            viewModel.ProductOffers(productOffers);
            alert(viewModel.ProductOffers());
        }
    });
    viewModel.totalQuantity = ko.computed(function () {
        var result = 0;
        ko.utils.arrayForEach(this.details(), function (item) {
            if (isNumber(item.Quantity())) {
                result += parseFloat(item.Quantity());
            }
        });
        return result;
    }, viewModel);
    ko.extenders.numeric = function (target, precision) {
        //create a writeable computed observable to intercept writes to our observable
        var result = ko.computed({
            read: target,  //always return the original observables value
            write: function (newValue) {
                var current = target(),
            roundingMultiplier = Math.pow(10, precision),
            newValueAsNum = isNaN(newValue) ? 0 : parseFloat(+newValue),
            valueToWrite = Math.round(newValueAsNum * roundingMultiplier) / roundingMultiplier;
                //only write if it changed
                if (valueToWrite !== current) {
                    target(valueToWrite);
                } else {
                    //if the rounded value is the same, but a different value was written, force a notification for the current field
                    if (newValue !== current) {
                        target.notifySubscribers(valueToWrite);
                    }
                }
            }
        });
        //initialize with current value to make sure it is rounded appropriately
        result(target());
        //return the new computed observable
        return result;
    };

    //Init Loading
    jQuery(document).ready(function () {
        //Ajax call gets the data from database in json form
    });
    function GetProductOffers(ProductID) {
        alert("Ajax call initiated.");
        var Val = "here ajax call is initiated";
        return Val;
    }
    //Binding ViewModel
    ko.applyBindings(viewModel);
</script>

我认为这部分代码需要根据当前的情况进行修改,我没有收到newValueviewModel.ProductOffers()的警报

viewModel.ProductID.subscribe(function (newValue) {
        viewModel.ProductOffers.removeAll();
        alert(newValue);
        if (newValue) {
            var productOffers = GetProductOffers(newValue);
            viewModel.ProductOffers(productOffers);
            alert(viewModel.ProductOffers());
        }
    });

我不知道为什么订阅不工作,但我使用了一个计算字段,它做得很好

self.ProductOffers = ko.computed(function () {
                if (typeof self.ProductID != "undefined" && self.ProductID() > 0) {
                    return GetProductOffers(self.ProductID());
                }
                else {
                    return "";
                }
            });