简体   繁体   中英

Knockout computed binding not updating the template name

I'm shifting to Knockout from JQuery bindings to make UI synchronization with data easier. I am fairly new to knockout but to keep things tidy I'm using knockout with Requirejs.

So in one of my modules I tried to use templates to change the information bar and bound the template name to a computed observable. But the computed observable is not updating the template name in the UI.

<div data-bind="template: { name: baseData.printListTemplate }"></div>

<script type="text/html" id="inPrintList">
    <span>
        <span>In </span>
        <a href="#" class="managePrintList">Print List</a>
    </span>

    <a href="#" data-bind="click: switchInPrintList">sw</a>
</script>

<script type="text/html" id="notInPrintList">
    <span>
        <span>Add to </span>
        <a href="#" class="managePrintList">Print List</a>
    </span>

    <a href="#" data-bind="click: switchInPrintList">sw</a>
</script>

Above is my html code and Knockout templates.

Following code is my Knockout module

Inside the baseData I have printListTemplate computed observable returning the templatename to use for print list indicator.

switchInPrintList changes the inPrintList observable and after the change ko.computed function runs and it returns the correct string but the UI is not updated after these.

define(['knockout', 'Modules/utils', 'Modules/Shared/kodialog'],
    function (ko, utils, kodialog) {

        var baseData = function (data) {
            var self = this;

            self.inPrintList = ko.observable(false);

            ko.mapping.fromJS(data, {}, self);

            self.printListTemplate = ko.computed(function () {
                if (self.inPrintList())
                    return "inPrintList";
                else
                    return "notInPrintList";
            }, this);
        }

        var baseDataMapping = {
            create: function (options) {
                return new baseData(options.data);
            }
        }

        return function player() {
            var self = this;

            var utils = new utils();

            self.baseData = new baseData();

            self.dialog = new kodialog();

            self.renderMP = function (contentId) {
                self.dialog.openDialog();
                $.ajax({
                    type: "GET",
                    url: "/Home/mpdata",
                    dataType: 'json',
                    crossDomain: true,
                    data: { contentid: contentId },
                    success: function (jsonResult) {
                        self.baseData = ko.mapping.fromJS(jsonResult, baseDataMapping);
                        self.dialog.rendered(true);
                    }
                });
            }
            self.switchInPrintList = function () {
                if (self.baseData.inPrintList())
                    self.baseData.inPrintList(false);
                else
                    self.baseData.inPrintList(true);
            }
        }
    });

I think the problem is that you're reassigning baseData in your success callback, when you need only to update it's properties accordingly. For this case there is another overload of ko.mapping.fromJS() method, which takes the third parameter as update target which properties should be updated. See documentation , "specifying update target".

So try to rewrite your success callback like this:

success: function (jsonResult) {
    ko.mapping.fromJS(jsonResult, baseDataMapping, self.baseData);
    self.dialog.rendered(true);
}

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