2013-02-26 59 views
5

我對Durandal來說相當新穎。我對KnockoutJS有一點經驗。我正在試圖從php文件中檢索json填充observableArray。然後我試圖將數組加載到表中。在第一次加載頁面時將數據加載到表中似乎存在問題。我執行system.log(客戶)只是爲了確保數據在observableArray中,它是。當我刷新頁面時,數據會像我想要的那樣加載到表格中。看起來好像observableArray正在被填充,但視圖沒有更新。如何在Durandal中使用observables?

我想知道我在做什麼錯,它不加載頁面的第一個負載。這裏是我玩過杜蘭達爾的測試網站: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); 
     } 
    }; 
}); 

此外,作爲一個側面說明,jQuery的頂部和激活底部函數僅在我將它們包含在setTimeout()函數中時才起作用。我以日期選擇器爲例。這並不重要,但如果有人知道如何解決這個問題,我也會非常感激。

回答

9

謝謝,保羅。我昨晚很晚。我忘了回覆添加答案。我從Durandal的創始人Rob Eisenberg那裏得到了答案。我的錯誤是我需要從.getJSON()調用返回承諾。我還需要在模塊中添加另一個函數viewAttached(),用於引用DOM中元素的所有jQuery調用。

這是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 
+0

謝謝smalone。這是我正在尋找的解決方案。 – Blaise 2013-03-06 21:18:17

+1

你很受歡迎。在我與之合作的幾周內,我對杜蘭達有了很多瞭解。這對於開發單頁面應用程序來說是一種救命。 – smalone 2013-03-21 21:40:09

+0

太棒了。感謝您發佈解決方案 – ajeeshpu 2013-05-01 05:54:22

0

我不知道自發布問題以來是否更改了任何內容,但它適用於IE 9,Opera 12和Chrome。在IE 9中有一個錯誤,lines 45 and 46shell.jsevent.currentTarget.classList有時候是空的,所以你應該檢查一下,但是如果我去你的應用並點擊Customers,那麼表中就有數據。

+0

我想通了,我的問題。我把它作爲上面的解決方案發布。感謝您檢查。 – smalone 2013-03-21 21:41:01

相關問題