2013-02-26 7 views
5

Durandal'a oldukça yeni geldim. KnockoutJS ile biraz tecrübem var. Ben bir php dosyasından alınan json bir gözlemlenebilirArray doldurmaya çalışıyorum. Ardından diziyi bir tabloya yüklemeye çalışıyorum. Verileri sayfanın ilk yüklemesi üzerine tabloya yüklerken bir sorun var gibi görünüyor. Verilerin gözlemlenebilirArray'da olduğundan emin olmak için bir system.log (müşteri) yapıyorum. Sayfayı yenilediğimde, veriler istediğim gibi tabloya yüklenir. GözlemlenebilirArray doluyormuş gibi görünür, ancak görünüm güncellenmez.Durandal'da gözlenebilirler nasıl kullanılır?

Sayfanın ilk yüklemesinde yüklenememesi nedeniyle ne yaptığımı merak ediyordum. İşte burada durandal ile test ettiğim test sitesi: http://dev.codeplanetapps.com/spa/. Yüklendikten sonra "Müşteriler" i tıklayın. Söz konusu sayfa http://dev.codeplanetapps.com/spa/#/customers. Bu sayfa doğrudan yüklendiğinde iyi çalışıyor, ancak uygulamayı ana sayfadan yükledikten sonra müşterilere geçtiğimde, tablo doğru şekilde yüklenmiyor. Herhangi bir yardım için şimdiden teşekkür ederiz. İşte

görünümüdür:

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

Ve burada ViewModel geçerli: activate bir yan not olarak, üstündeki jQuery ve altta olarak, aynı zamanda

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); 
     } 
    }; 
}); 

işlev, yalnızca onları bir setTimeout() işlevinde çevrelediğimde çalışır. Tarihçiyi örnek olarak bıraktım. Bu çok önemli değil, ama bunu nasıl düzelteceğini bilen varsa, bunu çok takdir ediyorum.

cevap

9

Teşekkürler, Paul. Dün gece geç kalmıştım. Cevabı eklemek için cevap vermeyi unuttum. Durandal'ın yaratıcısı Rob Eisenberg'den bir cevap aldım. Benim hatam, .getJSON() çağrısından verilen sözü geri vermem gerektiğiydi. Ayrıca, DOM'daki bir öğeye başvuran jQuery çağrılarımın tamamı için başka bir işlev olan viewAttached() öğesini eklemem gerekiyordu.

İşte Rob'un yanıtı Help with observableArray not updating in view. Bu grupta gerçekten yardımcı oluyorlar. Rob, çoğu soruya cevap vermek için oldukça hızlıdır.

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

Teşekkür ederim, Smalone. Aradığım çözüm bu. – Blaise

+1

Oldukça hoş geldiniz. Durandal hakkında birkaç hafta içinde çalışıyorum. Tek sayfa uygulamaları geliştirmek için bir hayat kurtarıcı oldu. – smalone

+0

Müthiş. çözümü için teşekkürler – ajeeshpu

0

Soruyu yayınladıktan sonra herhangi bir şeyi değiştirip değiştirmediğinizi bilmiyorum, ancak IE 9, Opera 12 ve Chrome'da benim için çalışıyor. shell.js'un numaralı numaralı lines 45 and 46 numaralı dosyada bir hata oluştu, bazen event.currentTarget.classList boştur, bu nedenle bunu kontrol etmelisiniz, ancak uygulamanıza gidip Müşteriler'i tıklarsam tabloda veri var.

+0

benim sorunun ne:

Aşağıda ViewModel için düzeltilmiş kodudur. Yukarıda bir çözüm olarak yayınladım. Kontrol ettiğin için teşekkürler. – smalone