knockout js data binding not updated

非 Y 不嫁゛ 提交于 2019-12-13 05:15:24

问题


I am working on a SPA that contains multiple areas that I dynamically load into a div (id=#main).

In order to achieve such I use SammyJS for the routing and knockoutjs for the binding. The particular subpage is loaded like $('#main').load('pages/subpage.html'); where the subpage contains two divs that are switched (master/detail pattern).

The data is loaded using .getJSON('data.php',....) into an observableArray within the knockout Model created.

Everything works fine and a list of the items is displayed when loading the page the firsttime.

When I select an Item and switch back to the list using the back-button, which simply invokes self.list() where I set the currentUser to null, instead of the proper list containing the items of the users array it shows the pure mask without any data-bindings regarded (both divs are shown).

The error: The list of items is not displayed anymore although the data is still there (which was checked using console.log(...). The data is definitely available and correct but somehow the binding is not updated ...

Here the particular code-sample:

<div data-bind="load: loadData()">

<div id="userlist" class="row" data-bind="visible: !currentUser()">
    <h1 class="lead">Please select a User ...</h1>
    <div class="twelve columns">
        <table class="striped rounded" data-bind="visible: users().length > 0">
            <thead>
                <tr>
                    <th>ID</th>
                    <th>First name</th>
                    <th>Last name</th>
                    <th>Email</th>
                    <th>Action</th>
                </tr>
            </thead>
            <tbody data-bind="foreach: users">
                <tr data-bind="click: $parent.show">
                    <td><span data-bind="text: id"></span></td>
                    <td><span data-bind="text: firstname"></span></td>
                    <td><span data-bind="text: lastname"></span></td>
                    <td>
                        <a class="default btn" data-bind="click: $parent.show">show</a>
                        <a class="default btn" data-bind="click: $parent.delete">delete</a>
                    </td>
                </tr>
            </tbody>
        </table>
    </div>
</div>

<!-- 
    User Details
-->
<div id="userdetails" class="row" data-bind="with: currentUser">
    <div class="breadcrumb"><span data-bind="click: $root.list">Userdetails &gt;</span> <span data-bind="text: name"></span></div>

    <div class="twelve columns">

        <table class="striped rounded">
        <tbody>
        <form></form>
            <tr class="field">
                <td><label class="inline" for="userFirstName">Firstname</label></td>
                <td style="width:100%"><input class="normal text input" name="userFirstName" type="text" placeholder="First name" data-bind="value: firstname"></td>
            </tr>
            <tr class="field">
                <td><label class="inline" for="userlastname">Firstname</label></td>
                <td style="width:100%"><input class="normal text input" name="userlastname" type="text" placeholder="Family name" data-bind="value: lastname"></td>
            </tr>

        </tbody>
        </table>

        <div>
            <div class="medium btn default"><a href="#" data-bind="click: $root.save">save</a></div>
            <span>&nbsp;</span>
            <div class="medium btn default"><a href="#" data-bind="click: $root.delete">delete</a></div>
            <div class="medium btn default"><a href="#/users">back</a></div>
        </div>
    </div>
</div>

<!-- 
    Knockout Models
-->
<script>

    ko.validation.init({ grouping : { deep: true, observable: true } });
    ko.validation.rules.pattern.message = 'Invalid.';

    ko.validation.configure({
        registerExtenders: true,
        messagesOnModified: true,
        insertMessages: true,
        parseInputAttributes: true,
        //messageTemplate: null,
        decorateElement: true
    });

    var userModel = function(){

        var self = this;
        self.id = ko.observable(); 

        self.firstname = ko.observable().extend({required: { message: 'First name is a required field.' }});
        self.lastname = ko.observable().extend({required: { message: 'Last name is a required field.' }});

        return self;
    };

    var userData = function(){

        var self = this;    
        self.users = ko.observableArray([]);
        self.currentUser = ko.observable();

        self.viewMode = ko.observable('list');

        self.list = function(){

            self.currentUser(null);
            self.viewMode('list');

            location.hash = '/users';
            console.log('list '+ self.users().length+ ' users');
            console.log(ko.toJSON(self.users()));

        };
        self.show = function(item){

            self.currentUser(item);
            self.viewMode('details');

            location.hash = '/users/' + item.id();
            console.log('show user:'+ko.toJSON(item));
        };

        self.loadData = function(){
            //fetch existing data from database

            console.log('loaddata - User');
            //self.users = ko.observableArray([]);

            $.getJSON("pages/user.php", function(data) { 

                    data.forEach(function(item){

                        var newModel = new userModel();
                        newModel.id(item['id']);
                        newModel.firstname(item['firstname']);
                        newModel.lastname(item['lastname']);

                        self.users.push(newModel);

                    });
            });

        }
    }

    if (!_userData){

        var _userData = new userData();
        ko.applyBindings(_userData);

    }

</script>

来源:https://stackoverflow.com/questions/19319021/knockout-js-data-binding-not-updated

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!