0

我正在开发一个包含多个区域的 SPA,这些区域可以动态加载到 div (id=#main) 中。

为了实现这一点,我使用 SammyJS 进行路由,并使用 knockoutjs 进行绑定。特定子页面的加载就像$('#main').load('pages/subpage.html');子页面包含两个切换的 div(主/详细模式)一样。

数据被加载.getJSON('data.php',....)到创建的淘汰模型中的 observableArray 中。

一切正常,第一次加载页面时会显示项目列表。

当我选择一个项目并使用后退按钮切换回列表时,它只是调用self.list()我将 currentUser 设置为的位置null,而不是包含用户数组项目的正确列表,它显示纯掩码,没有考虑任何数据绑定(显示了两个 div)。

错误:尽管数据仍然存在,但不再显示项目列表(已使用 进行检查console.log(...)。数据绝对可用且正确,但不知何故绑定未更新...

这里是特定的代码示例:

<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>
4

0 回答 0