Search code examples
javascripttemplatesknockout.jsjavascript-frameworkknockout-templating

How to have both visible and template binding for Knockout.js


What is the right way to have different bindings on the same target in Knockout.

These didn't seem to work:

<div data-bind="template: { name: 'voucher-template', foreach: voucher }" data-bind="visible: showVoucher"></div>

or

<div data-bind="template: { name: 'voucher-template', foreach: voucher }, visible: showVoucher"></div>

Full Test code:

<script>

        function VoucherViewModel() {
            this.voucher = [
            {
                VoucherNumber: "100000",
                VoucherImage: "someurl",
                VoucherExpiry: "20/3/12",
                VoucherRedeemed: true,
                VoucherDesc: "ddwqdwqdwqd",
                VoucherPuchaseDate: "20/12/11",
                VoucherPrice: "50"
            }, 
            {
                VoucherNumber: "200000",
                VoucherImage: "someurl",
                VoucherExpiry: "20/3/12",
                VoucherRedeemed: true,
                VoucherDesc: "ddwqdwqdwqd",
                VoucherPuchaseDate: "20/12/11",
                VoucherPrice: "50"
            }]
        };

        var viewModel = {
            showVoucher: ko.observable(true)
        };

        $(function () {

            //VIEWMODEL
            ko.applyBindings(viewModel);

            //TEMPLATES
            ko.applyBindings(new VoucherViewModel());

        });
    </script>






<div data-bind="template: { name: 'voucher-template', foreach: voucher }, visible: showVoucher"></div>        
<script type="text/html" id="voucher-template">
<h3 data-bind="text: VoucherNumber"></h3>
</script>

Solution

  • Seems like the double ko.applyBindings is causing an issue.

    This worked:

    $(function () {
    
                var viewModel = {
                    showVoucher: ko.observable(true),
                    voucher: ko.observableArray([
                        {
                            VoucherNumber: "100000",
                            VoucherImage: "someurl",
                            VoucherExpiry: "20/3/12",
                            VoucherRedeemed: true,
                            VoucherDesc: "ddwqdwqdwqd",
                            VoucherPuchaseDate: "20/12/11",
                            VoucherPrice: "50"
                        },
                        {
                            VoucherNumber: "200000",
                            VoucherImage: "someurl",
                            VoucherExpiry: "20/3/12",
                            VoucherRedeemed: true,
                            VoucherDesc: "ddwqdwqdwqd",
                            VoucherPuchaseDate: "20/12/11",
                            VoucherPrice: "50"
                        }
                    ])
                };
    
                //VIEWMODEL
                ko.applyBindings(viewModel);    
    
    
            });
    

    If there is a better way to write this, please let me know.

    Edited version below, also trying out mapping:

    <script>
    
            function getVoucherData() {
                //some ajax call;
    
                return data = { "voucher" : [{
                    VoucherTitle: "Offer title 1",
                    VoucherNumber: "100000",
                    VoucherImage: "someurl",
                    VoucherExpiry: "20/3/12",
                    VoucherRedeemed: true,
                    VoucherDesc: "ddwqdwqdwqd",
                    VoucherPuchaseDate: "20/12/11",
                    VoucherPrice: "50"
                },
                {
                    VoucherTitle: "Offer title 2",
                    VoucherNumber: "200000",
                    VoucherImage: "someurl",
                    VoucherExpiry: "20/3/12",
                    VoucherRedeemed: true,
                    VoucherDesc: "ddwqdwqdwqd",
                    VoucherPuchaseDate: "20/12/11",
                    VoucherPrice: "50"
                }]
                };
            }
    
            function initViewModel() {
                var viewModel = {};
    
               // PAGE SETUP
               viewModel.showVoucher = ko.observable(true);
               viewModel.showMyAccount = ko.observable(false);
    
               // GET VOUCHER
               var voucherData = getVoucherData();
               voucherData.voucher.sort(function (left, right) {
                    return left.VoucherNumber > right.VoucherNumber
               });
               viewModel.voucher = ko.mapping.fromJS(voucherData.voucher);
    
               // START
               ko.applyBindings(viewModel);
           }
    
           $(function () {
               initViewModel();        
           });
        </script>