Pregunta

I have previoiusly posted and solved my problem here, but now when i tried to put that solution in my orignal application i'm facing difficulties, again the dropdowns are not working as they are working in testing page, this is my code

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>

I think this portion of the code needs to be modified according to current scenario, I'm not getting the alert for newValue or viewModel.ProductOffers()

viewModel.ProductID.subscribe(function (newValue) {
        viewModel.ProductOffers.removeAll();

        alert(newValue);

        if (newValue) {
            var productOffers = GetProductOffers(newValue);
            viewModel.ProductOffers(productOffers);
            alert(viewModel.ProductOffers());
        }
    });
¿Fue útil?

Solución

I had no idea why subscribe was not working but instead i used a computed field and it has done the job quite well

self.ProductOffers = ko.computed(function () {
                if (typeof self.ProductID != "undefined" && self.ProductID() > 0) {
                    return GetProductOffers(self.ProductID());
                }
                else {
                    return "";
                }
            });
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top