简体   繁体   中英

Render partial view using knockout.js

I have a requirement to load tabs based on user selection in Asp.Net MVC4. Each tab element pertains to a partial view. Each partial view has its own knockout.js bindings.

On click of each tab, partial view needs to be rendered below the previously selected tab.

Here is a code snippet

<div class="row-fluid top-pad-double" id="tabBasedGrowthDiv">
  <ul class="nav nav-pills">
     <li><a href="#tabCustomerInfo" data-toggle="tab" data-bind="click:$root.AddTab">CustomerInfo</a></li>
     <li><a href="#tabPropertyInfo" data-toggle="tab" data-bind="click: $root.AddTab">PropertyInfo</a></li>
     <li><a href="#tabPropertyInfo1" data-toggle="tab" data-bind="click: $root.AddTab">PropertyInfo1</a></li>   
</ul>
<div class="tab-content pills pill-sections">
    <div data-bind="template: { name: 'tabBasedGrowthTemplate', foreach: $root.tabs}"></div>
    </div>
</div>

Knockout.js Html Template

<script type="text/html" id="tabBasedGrowthTemplate">
    <div class="tab-pane" >
        <div class="pill-header clearfix">
            <h3>Some title</h3>
                <div class="pull-right">
                    <a href="#" class="btn btn-mini" data-toggle="button" rel="tooltip" data-title="lock this section here" data-placement="top"><i class="icon-lock"></i></a>
                    <a href="#" class="btn btn-mini" rel="tooltip" data-title="close this section" data-placement="left"><i class="icon-remove"></i></a>
                </div>
        </div>
        <div class="pill-content" data-bind="attr:{id: $data.id}">

            @Html.Partial("tab based partial view name")

        </div>
    </div>
</script>

This is the approximate implementation of the view model.

function TabBasedGrowthViewModel() {
        var self = this;

        self.tabs = ko.observableArray([TabViewModel]);
        self.AddTab = function (){}
}

Knockout bindings

<script type="text/javascript">
    $(document).ready(function () {
        ko.applyBindings(new TabBasedGrowthViewModel(), $("#tabBasedGrowthDiv").get(0));
        });
</script>

When I do the above steps I am having a conflict with knockout bindings of the main view model where the partial view is rendered, as it has its own knockout bindings. I am getting this conflicts only if I render the partial view using the knockout template as shown in above Knockout.js Html Template sub-heading.

Any help would be highly appreciated.

Thanks in advance, Alphacoder

I've done something similar by having a NavigationViewModel that is bound to the page and knows what view you want to show and stores that in an observable variable. Then around each tab, you use the visible test to see whether it should be shown based on that variable.

You then want to set the page up to allow you to bind different view models to different partial views, and you set this up using:

// This lets us stop the view model from binding to areas of the page,
// allowing us to bind different objects to parts of the page
ko.bindingHandlers.stopBinding = {
    init: function ()
    {
        return { controlsDescendantBindings: true };
    }
};

ko.virtualElements.allowedBindings.stopBinding = true;
ko.applyBindings(navigationViewModel);

Then in your partial view, you use this code to stop the navigation view model from being bound to it:

    <section data-bind="visible: SelectedView() == 'location'">
        <!-- ko stopBinding: true -->        
        <div id="map"></div>
        <!-- /ko -->
    </section>

And bind your other model to this section using:

        ko.applyBindings(mapViewModel, $('#map')[0]);

Granted, I haven't done this with a template, but that works when using plain html and js with knockout.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM