Multiple Knockout.JS Model in one page (Master-child relationship page).

In order for you to create a real world application you need to have the audacity to manipulate multiple tables with tons of fields in one view.  If your view is a web page, it’s a nightmare.

The solution is plain organization.  Just organized.  But how? Try Knockout.JS.

b1

The image above depicts where your Knockout.JS Model is positioned to organized the data sent and received between the client (browser) and your database via the controller (web api).

The 1st step is to declare a Knockout.JS name space.

        var $koNamespace = {};

The 2nd step is to declare the model variables.  I have two of them, the Item (detail) and the ItemPrice (child).

        var $koItemModel;
        var $koItemPriceModel;

The 3rd step is the initialization of the models. The initialization is tricky, because you need to know the fields of your database and the controls in your html page file. Furthermore, your page may contain the same control name, thus you must add a Section tag to group those controls.

        $koNamespace.initItem = function (Item) {
            var self = this;

            self.Id = ko.observable(!Item ? 0 : Item.Id);
            self.ArticleId = ko.observable(!Item ? 0 : Item.ArticleId);
            self.AccountId = ko.observable(!Item ? 0 : Item.AccountId);
            self.UnitId = ko.observable(!Item ? 0 : Item.UnitId);
            self.PurchaseTaxId = ko.observable(!Item ? 0 : Item.PurchaseTaxId);
            self.SalesTaxId = ko.observable(!Item ? 0 : Item.SalesTaxId);
            self.ItemCode = ko.observable(!Item ? "" : Item.ItemCode);
            self.Item = ko.observable(!Item ? "" : Item.Item);
            self.BarCode = ko.observable(!Item ? "" : Item.BarCode);
            self.Category = ko.observable(!Item ? "" : Item.Category);
            self.Unit = ko.observable(!Item ? "" : Item.Unit);
            self.Account = ko.observable(!Item ? "" : Item.Account);
            self.PurchaseTax = ko.observable(!Item ? "" : Item.PurchaseTax);
            self.SalesTax = ko.observable(!Item ? "" : Item.SalesTax);
            self.Remarks = ko.observable(!Item ? "" : Item.Remarks);
            self.IsAsset = ko.observable(!Item ? false : Item.IsAsset);

            return self;
        };

        $koNamespace.initItemPrice = function (ItemPrice) {
            var self = this;

            self.Id = ko.observable(!ItemPrice ? 0 : ItemPrice.Id);
            self.ArticleId = ko.observable(!ItemPrice ? 0 : ItemPrice.ArticleId);
            self.PriceDescription = ko.observable(!ItemPrice ? "NA" : ItemPrice.PriceDescription);
            self.Price = ko.observable(!ItemPrice ? 0 : ItemPrice.Price);

            return self;
        }

In the above code:  There are two initialization functions representing each model.  The function accepts an Object that may be null, so I need to put in the necessary checked (similar to IIF) in the observable method.  This type of checked enables me to perform both Add and Edit function using the same model.  Cool eh!

The 4th and last step is the binding.

        // Item Binding
        $koNamespace.bindItem = function (Item) {
            var viewModel = $koNamespace.initItem(Item);
            ko.applyBindings(viewModel, $("#ItemDetail")[0]); //Bind the section #ItemDetail
            $koItemModel = viewModel;
        }

        // Item Price Binding
        $koNamespace.bindItemPrice = function (ItemPrice) {
            try {
                var viewModel = $koNamespace.initItemPrice(ItemPrice);
                ko.applyBindings(viewModel, $("#itemPriceDetail")[0]); //Bind the section #itemPriceDetail (Modal)
                $koItemPriceModel = viewModel;
            } catch (e) {
                $koItemPriceModel['Id'](!ItemPrice ? 0 : ItemPrice.Id);
                $koItemPriceModel['ArticleId'](!ItemPrice ? 0 : ItemPrice.ArticleId);
                $koItemPriceModel['PriceDescription'](!ItemPrice ? "" : ItemPrice.PriceDescription);
                $koItemPriceModel['Price'](!ItemPrice ? 0 : ItemPrice.Price);
            }
        }

In the code above, I created two bindings, one for every model.  The first binding is the binding of my detail page called Item, as you can see, it is just a very simple binding, just take note of the Section tag.  The second binding is tricky, why is that? because the ItemPrice is a modal entry that can be called multiple times by the user (see the screen shots).  Knockout.JS disallows multiple binding on the same controls.

Thats it!  But before I go let me show you the screen shots of the running application:

b4

b1

If you find this blog helpful, you can make the donation by clicking the Paypal button below.

Advertisements
About

Software developer living in the Philippines.

Posted in ASP.NET

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Author

Harold Glenn P. Minerva
Software Developer / Tech Enthusiast
Living in the Philippines

View Harold Glenn Minerva's profile on LinkedIn

Instagram

Software Engineer - Seasonal and Range Trading Software. Magenta Trader is a powerful stock market visualization software that increases your probability of trading success.

Software Architect and Founder - Easyfis.com is a multi-tenant cloud-based Software-as-a-Service (SaaS) business app that caters to micro, small and medium trading businesses.

CTO and Co-Founder - We give your company the leverage by providing innovative software solutions products such as Point-of-Sales (POS), Financial Information System (FMIS), Payroll and DTR (HRIS), and many more.

%d bloggers like this: