2014-12-03 16 views
10

PagerJS URL parametrelerini alabilir ve bunları modele bağlayabilir. Eğer bağlantıyı tıkladığınızda Örneğin, PagerJS web (see link) Bu örnekte, "Philip Fry" göstererek, bu #/user?first=Philip&last=Fry nereye taşınacak ve veriyle alt sayfa görünecektir:PagerJS URL paramları ile "iki yönlü bağlama" nasıl yapılır?

<a class="btn" data-bind="page-href: {path: 'user', params: {first: 'Philip', last: 'Fry'}}">Send parameter to page</a> 

<div data-bind="page: {id: 'user', params: ['first','last']}" class="well-small"> 
    <div> 
     <span>First name:</span> 
     <span data-bind="text: first"></span> 
    </div> 
    <div> 
     <span>Last name:</span> 
     <span data-bind="text: last"></span> 
    </div> 
</div> 

Bu tek yönlü bir bağlantıdır: Gözlemlenebilir değişiklikler, sayfadaki kullanıcı eylemleri nedeniyle URL güncellenmez.

nedir PagerJS kullanırken gözlenebilirlerin ile senkronize URL parametrelerini tutmanın önerilen yöntem?

Ben o/o başkalarına veya imi URL'yi paylaşabilmeniz için URL parametreleri, UI kontrolleri bir demet seçerek üretilen kullanıcının dinamik olarak oluşturulan arama-kriterlerini saklamak istediğinizi

, tüm sayfayı yenilemeden , tabii ki.

+0

+1. IMO, en iyi çözüm, kontrollere açıkça bağlı olmayacaktır (ör.kontroller navigasyon üretmez, ancak değişikliklerini kendi varlığını güvenle kabul edebilen ve farklı bir versiyonuna gidebilen page viewmodel'e iletir. – TheHansinator

cevap

5

Yasal Uyarı: Ben pager.js hakkında hiçbir şey bilmiyorum, ama benim genel nakavt deneyim hala yardımcı olacağını umuyorum. bağlama örneğin bakıldığında

, page URL'den başlangıç ​​değerleri kullanarak görünür değişikliklerin oluşturmak gibi görünüyor. İlk içgüdüm bu bağlayıcıyı genişletmek ve bu değerlerin her birinin aboneliğinin URL'yi güncellediğinden emin olmak olacaktır.

Let isminin twoway-page bağlayıcı:

ko.bindingHandlers["twoway-page"] = { 
    init: function(element, valueAccessor, allBindings, viewModel, bindingContext) { 
    // Call pager.js' page binding 
    ko.bindingHandlers.page.init(element, valueAccessor, allBindings, viewModel, bindingContext); 

    // ... 
    } 
} 

Ve örnek üzerinde diyoruz bağlayıcı oluyor:

<div data-bind="twoway-page: { 
        id: 'start', 
        params: ['first','last'] 
       }"> 

page.init çağırdıktan sonra bağlama sayfa ViewModel genişletti, tanımlanan gözlenebilirleri ekleyerek params dizesi, viewModel nesnesine. Bu, bu gözlenebilirlerdeki değişikliklere abone olabileceğimiz anlamına gelir.

sonraki hedefi, doğru karma bilgisayar edilir. page-href bağının href özniteliğini nasıl hesapladığını araştırdım. Tersine, path ve params özelliğine sahip bir nesnede pager.page.path() özelliğini kullanır. Hesaplanan bir gözlemlenebilir içinde benzer bir nesne oluşturmaya çalıştım.

// ... 
var options = valueAccessor(); 
var pathObj = ko.computed(function() { 

    var result = { 
     path: options.id, 
     params: {} 
    }; 

    options.params.forEach(function(param) { 
     result.params[param] = viewModel[param](); 
    }); 

    return result; 
}).extend({ rateLimit: { timeout: 200, method: "notifyWhenChangesStop" } }); 
Bir pager.js yöntemi ile karma güncellemek için bir "temiz" bir yol bulamadık ama içten, pagerjs da var gibi görünüyor olsa da (bir değer ayarlamak için location.hash = "newhash" kullandığı fark ettiniz

tarih/html5 alternatifi ...).

<div> 
    <span>First name:</span> 
    <input type="text" data-bind="textInput: first"> 
</div> 
: yerine örnekten text bağları, böylece biz değerleri güncelleyebilirsiniz textInput bağlamaları kullanacağız, Şimdi

// ... 
pathObj.subscribe(function(newValue) { 
    location.hash = pager.page.path(newValue); 
}); 

: Neyse, biz karma güncellemek için bizim gözlemlenebilir abone olabilirsiniz

Yani, tamamlamayı:

  1. varolan çağrı cihazı uzatmak için en iyi tahmin olurdu.js ciltleme
  2. URL'de güncellenmesi gereken tüm yeniliklere abonelikler oluşturun
  3. Değerler değiştiğinde karma değeri otomatik olarak güncelleyin; Konumu karma ile malzeme yapmak güncellemeleri

aşırı yüklenmesini önleyecek bir rateLimit uzantısını kullanmak Turp göstermek biraz zor, bu yüzden kavramı benim belgesinin bir gif kaydettik:

live updating the hash using a custom pagerjs binding

komple özel bağlama kodudur: yüzden yeni bir yanıt eklemek zorunda ben bir yorum ekleyemezsiniz

ko.bindingHandlers["twoway-page"] = { 
    init: function(element, valueAccessor, allBindings, viewModel, bindingContext) { 
     ko.bindingHandlers.page.init(element, valueAccessor, allBindings, viewModel, bindingContext) 

     var options = valueAccessor(); 

     var pathObj = ko.computed(function() { 

      var result = { 
       path: options.id, 
       params: {} 
      }; 

      options.params.forEach(function(param) { 
       result.params[param] = viewModel[param](); 
      }); 

      return result; 
     }).extend({ rateLimit: { timeout: 200, method: "notifyWhenChangesStop" } }); 

     pathObj.subscribe(function(newValue) { 
      location.hash = pager.page.path(newValue); 
     }) 

     return { controlsDescendantBindings: true } 
    } 
}; 
2

. user3297291 tarafından çok güzel yanıt, gerçekten çok yardımcı oldu.

  1. derin navigasyon: sayfaları, alt sayfalar, subsubpages, options.id yeterli, biz (#!/ olmadan) tam yolunu page/subpage/subsubpage gerekmez vb

  2. Ancak, bazı sorunlar, örneğin gerçek dünyada ortaya çıkan
  3. Sayfalar arasında bazı URL paramlarını paylaşırken, param her değiştiğinde, her sayfa bir gezinmeyi tetikleyecektir, sonuncusu görüntülenecektir. Bazı sayfalar arasında aynı ID paramlarını paylaşıyorum (productID, vs).

    ...var options = valueAccessor(); 
    var parent = pager.getParentPage(bindingContext); 
    var fullroute = parent.getFullRoute()(); 
    if(fullroute.length == 0) 
        var path = fullroute.join('/')+options.id; 
    else 
        var path = fullroute.join('/')+'/'+options.id; 
    

    result nesne dönüşür:

sayısında 1 için, tam yolu hesaplamak konuyla 2 için

var result = { 
    path: path, 
    params: {} 
}; 

, biz onlar sadece navigasyon tetikleyebilir olduğunu anlatmak zorunda aktif sayfa kendi olduğunda.

abone yöntemiyle İçimizde activePage yolunu hesaplar ve bunları karşılaştırır:

:

Ayrıca
pathObj.subscribe(function(newValue) { 
    //calculate activePath 
    var activeParent = pager.activePage$().parentPage.getFullRoute()(); 
    var activeId = pager.activePage$().getCurrentId(); 
    if(activeParent.length == 0) 
     var activePath = activeParent .join('/')+activeId; 
    else 
     var activePath = activeParent .join('/')+'/'+activeId; 

    if(path == activePath){ 
     location.hash = pager.page.path(newValue); 
    } 
}) 

, atış params döngü zaman varsayılan değerler sunup sunmadığını, bir dizi veya bir nesne olabilir dikkatli olmak

<div data-bind="page: {id: 'search', params: ['product','price']}" class="well"> 

ihtiyaçlar:

options.params.forEach(function(param) {... 

Vs

<div data-bind="page: {id: 'search', params: {'product': null,'price': 0}}" class="well"> 

gibi bir şey gerekir: Cevabınız için user3297291 tekrar

Object.keys(options.params).forEach(function(key,index) { 
    result.params[key] = viewModel[key](); 
} 

teşekkür, gerçekten fark yarattı. Bunun için

İlgili konular