【问题标题】:How to use observables in Durandal?如何在 Durandal 中使用 observables?
【发布时间】:2013-02-11 13:45:39
【问题描述】:

我对 Durandal 很陌生。我对 KnockoutJS 有一点经验。我正在尝试从从 php 文件中检索到的 json 填充 observableArray。然后我试图将数组加载到表中。首次加载页面时将数据加载到表中时似乎存在问题。我执行 system.log(customers) 只是为了确保数据在 observableArray 中,它就是。当我刷新页面时,数据会按我想要的方式加载到表中。看起来好像 observableArray 正在填充,但视图没有更新。

我想知道我做错了什么,因为它没有在页面的第一次加载时加载。这是我一直在玩 durandal 的测试站点:http://dev.codeplanetapps.com/spa/。加载后,单击“客户”。有问题的页面是http://dev.codeplanetapps.com/spa/#/customers。直接加载该页面时,它可以正常工作,但是当我从主页加载应用程序然后切换到客户时,它无法正确加载表格。提前感谢您的帮助。

这里是视图:

<div>
<!-- Form to add new customer -->
<form class="form-inline customerForm">
    <span>Add New Customer</span>
    <input type="text" data-bind="value: inputName" placeholder="Name" />
    <input type="text" class="date input-small" data-bind="value: inputDOB" placeholder="Date of Birth" />
    <input type="text" class="input-small" data-bind="value: inputPhone" placeholder="Phone" />
    <input type="text" data-bind="value: inputEmail" placeholder="Email" />
    <button type="submit" class="btn btn-primary" data-bind="click: submitCustomer">Add</button>
</form>

<table class="table table-hover table-bordered customerTable">
    <thead>
        <tr>
            <th>Name</th>
            <th>DOB</th>
            <th>Phone Number</th>
            <th>Email</th>
            <th></th>
        </tr>
    </thead>
    <tbody data-bind="foreach: customers">
        <tr>
            <td data-bind="text: name"></td>
            <td data-bind="text: dob"></td>
            <td data-bind="text: phone"></td>
            <td data-bind="text: email"></td>
            <td><button class="btn btn-danger btn-mini" data-bind="click: $root.removeCustomer">Delete</button></td>
        </tr>
    </tbody>
</table>

这是视图模型:

define(function(require){ 
    // Load System for debugging
    var system = require('durandal/system');

    // Customer Structure
    function Customer(data) {
        this.name  = ko.observable(data.name);
        this.dob   = ko.observable(data.dob.substring(5,7) + '/' 
            + data.dob.substring(8,10) + '/' + data.dob.substring(0,4));
        this.phone = ko.observable(data.phone);
        this.email = ko.observable(data.email);
    };

    // Form observables
    var inputName  = ko.observable('');
    var inputDOB   = ko.observable('');
    var inputPhone = ko.observable('');
    var inputEmail = ko.observable('');
    // Customers array
    var customers = ko.observableArray([]);

    return {
        inputName: inputName,
        inputDOB: inputDOB,
        inputPhone: inputPhone,
        inputEmail: inputEmail,
        customers: customers,
        // This performs any needed functionality after the page loads
        activate: function(data) {
            // Change the selected nav item 
            $('.customerNav').addClass('active');
            $('.firstNav').removeClass('active');
            $('.secondNav').removeClass('active');

            // Get current customers from database and add to customers observableArray
            $.getJSON(
                // Backend script
                'php/query.php', 
                // Variables sent to query.php
                {
                    mode: 'select', 
                    table: 'customers', 
                    'fields[]': '*', 
                    'values[]': '*'
                }, 
                // Callback function
                function(data) {
                    var customer = $.map(data, function(item) {return new Customer(item) });
                    customers(customer);
                }
            );

            // For some reason I couldn't get the datepicker to work without make the page 
            // wait 50 milliseconds.
            setTimeout(function() {
            $('.date').datepicker();
            },500);
        }
    };
});

另外,附带说明一下,activate 函数顶部和底部的 jQuery 仅在我将它们包围在 setTimeout() 函数中时才起作用。我以日期选择器为例。它不是那么重要,但如果有人也知道如何解决这个问题,我将不胜感激。

【问题讨论】:

    标签: knockout.js durandal


    【解决方案1】:

    我不知道您在发布问题后是否进行了任何更改,但它适用于 IE 9、Opera 12 和 Chrome。 IE 9 中抛出错误,shell.js 中的lines 45 and 46event.currentTarget.classList 有时为 null,因此您应该检查一下,但是如果我转到您的应用并单击客户,则表中有数据。

    【讨论】:

    • 我发现了我的问题。我将其发布为上面的解决方案。感谢您的检查。
    【解决方案2】:

    谢谢,保罗。我昨晚很晚才起床。我忘了回复以添加答案。我从 Durandal 的创造者 Rob Eisenberg 那里得到了答案。我的错误是我需要从 .getJSON() 调用中返回承诺。我还需要为所有引用 DOM 中元素的 jQuery 调用向模块中添加另一个函数 viewAttached()。

    这是 Rob 对Help with observableArray not updating in view 的回复。他们在这个小组中真的很有帮助。 Rob 可以很快回答大多数问题。

    以下是视图模型的更正代码:

    define(function(require){ 
    // Load System for debugging
    var system = require('durandal/system');
    
    // Customer Structure
    function Customer(data) {
        this.name  = ko.observable(data.name);
        this.dob   = ko.observable(data.dob.substring(5,7) + '/' 
            + data.dob.substring(8,10) + '/' + data.dob.substring(0,4));
        this.phone = ko.observable(data.phone);
        this.email = ko.observable(data.email);
    };
    
    // Form observables
    var inputName  = ko.observable('');
    var inputDOB   = ko.observable('');
    var inputPhone = ko.observable('');
    var inputEmail = ko.observable('');
    // Customers array
    var customers = ko.observableArray([]);
    
    return {
        inputName: inputName,
        inputDOB: inputDOB,
        inputPhone: inputPhone,
        inputEmail: inputEmail,
        customers: customers,
        // This allows us to add jQuery as usual
        viewAttached: function() {
            // Change the selected nav item 
            $('.customerNav').addClass('active');
            $('.firstNav').removeClass('active');
            $('.secondNav').removeClass('active');
    
            $('.date').datepicker();
        },
        // This performs any needed functionality after the page loads
        activate: function(data) {
            // Capture the module instance
            var self = this;
    
            // Get current customers from database and add to customers observableArray
            var promise = $.getJSON(
                // Backend script
                'php/query.php', 
                // Variables sent to query.php
                {
                    mode: 'select', 
                    table: 'customers', 
                    'fields[]': '*', 
                    'values[]': '*'
                }, 
                // Callback function
                function(data) {
                    var customer = $.map(data, function(item) {return new Customer(item) });
                    system.log(customers);
                    self.customers(customer);
                }
            );
    
            return promise;
        }
    };
    }); // define
    

    【讨论】:

    • 谢谢你,斯马龙。这就是我一直在寻找的解决方案。
    • 不客气。在与 Durandal 合作的几周内,我学到了很多关于 Durandal 的知识。它是开发单页应用程序的救命稻草。
    猜你喜欢
    • 2014-10-17
    • 2015-11-09
    • 1970-01-01
    • 2014-05-10
    • 2019-12-10
    • 1970-01-01
    • 1970-01-01
    • 2016-09-29
    • 1970-01-01
    相关资源
    最近更新 更多