observable的subscribe函数不能正常工作

时间:2014-05-12 09:47:34

标签: javascript jquery asp.net knockout.js

我已预先发布并解决了我的问题,但现在当我试图将该解决方案放入我的orignal应用程序中时,我遇到了困难,再次下拉列表无法正常工作,因为他们正在测试页面,这是我的代码

this is my previous question

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

1 个答案:

答案 0 :(得分:0)

我不知道为什么订阅不起作用,而是我使用了计算字段并且它已经完成了相当好的工作

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