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

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