2012-09-06 29 views
10

Knockout.js'de yeni.Knockout.js ile Giriş Alanı() Girin

bir <input /> görünür hale gelir select() için iyi yolu nedir?

Görünüm:

<p> 
    Name: 
    <b data-bind="visible: !editing(), text: name, click: edit">&nbsp;</b> 
    <input data-bind="visible: editing, value: name, hasfocus: editing" /> 
</p> 

ViewModel:

function PersonViewModel(name) { 
    // Data 
    this.name = ko.observable(name); 
    this.editing = ko.observable(false); 

    // Behaviors 
    this.edit = function() { this.editing(true) } 
} 

ko.applyBindings(new PersonViewModel("Bert Bertington")); 

http://knockoutjs.com/documentation/hasfocus-binding.html

http://jsfiddle.net/RnCUd/

teşekkürler!

cevap

18

Seçimi işlemek için yeni bir ciltleme oluşturabilirsiniz.

ko.bindingHandlers.selected = { 
    update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
     var selected = ko.utils.unwrapObservable(valueAccessor()); 
     if (selected) element.select(); 
    } 
}; 

Bu bağlamayı giriş alanınıza ekleyin.

ko.bindingHandlers.hasSelectedFocus = { 
    init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
     ko.bindingHandlers['hasfocus'].init(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext); 
    },   
    update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
     ko.bindingHandlers['hasfocus'].update(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext);   

     var selected = ko.utils.unwrapObservable(valueAccessor()); 
     if (selected) element.select(); 
    } 
}; 

Bu sadece bağlama delegeler başlatma ve güncelleme hasfocus için: Alternatif http://jsfiddle.net/RnCUd/2/


, sen hasfocus bağlama sarar hangi bir özel bağlama oluşturabilirsiniz: Burada

<input data-bind="visible: editing, value: name, hasfocus: editing, selected: editing" /> 

bir keman olduğunu ve gözlemlenebilir olanın doğru olması durumunda öğenin seçilmesiyle ilgilenir. hasfocus yerine kullanın. Yukarıda özel bağlama John Earles kullanmayı denedi http://jsfiddle.net/RnCUd/1/

+0

Hızlı yanıt için teşekkürler :) bu noktada özel bağlamaları * çok fazla * kullanıyor? Belki de bu ** en iyisidir **, ama özel bağlamaları önceden olduğunu düşünmüştüm ... özel bağlamaları kullanmayan "yeterince iyi" bir yol var mı? Ya da özel bağlayıcılar büyük bir anlaşma değil ve bunları nasıl erken ve sıklıkla kullanacağımı öğrenmeliyim? (Not: Ben özel jQuery seçiciler yapmak için hiç biri değildi) :) –

+2

@QuangVan Özel bağlamaları tanımak için sizi teşvik ediyorum. Sorun verileriniz ile DOM arasındaki satırı geçtiğinde ve standart bağlamalar tarafından çözülemediğinde, özel bağlamalar doğru seçimdir. Söylediğin gibi "onları erken ve sık kullan" için özgür hissetmeni söyleyebilirim. Son çare olmaması gereken güçlü bir araçtır. –

+0

tamam yeh, "son çare" olmanın zihniyetini yaşadım ... Teşekkür ederim :) –

1

(Teşekkürler John!) Birlikte aynı zamanda bir valueUpdate kullanılan bir metin alanıyla: bağlayıcı 'afterkeydown' ve öğrendim İşte

<input data-bind="visible: editing, value: name, hasSelectedFocus: editing" /> 

bir keman olduğunu Bu gerçekten beklendiği gibi çalışmıyordu. (Bunun sebebi, bağlayıcılardan birinin ateşlenmesi gerektiğinde tüm bağların tekrar ateş etmesi ve her bir karakter yazıldıktan sonra değerin büyük olasılıkla yangına bağlanmasına neden olmasıdır).

Birkaç denemeden sonra, bu sorun için benim için uygun görünen bir yarı çözüm yaptım. Temel fikir, hasfocus bağlayıcısını ateşlemeden önce, söz konusu öğenin zaten odaklanıp odaklanmadığını kontrol etmemizdir ve biz aslında, aslında öğe, hasfocus bağlaması tetiklenmeden önce odaklama yapıldığında metni seçmemizdir.

Odağı kontrol etmek için jquery kullandım, ancak muhtemelen başka bir şekilde de yapabilirsiniz.

ko.bindingHandlers.hasSelectedFocus = { 
    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
     ko.bindingHandlers['hasfocus'].init(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext); 
    }, 
    update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
     var focusBefore = $(element).is(':focus'); 
     ko.bindingHandlers['hasfocus'].update(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext); 

     var selected = ko.utils.unwrapObservable(valueAccessor()); 
     if (selected && !focusBefore) { 
      element.select(); 
     } 
    } 
}; 

Düzenleme: iOS cihazda kullanıldığında istediğiniz gibi bağlama bu tür tam olarak çalışmayabilir fark ettik. Böyle bir bağlanmada yanlış bir şey yoktur, ancak otomatik odaklama ve seçim mantığı, aygıtın klavyesinin, bu tür bir aygıtta tam olarak olmasını istediğiniz bir şey olabilecek veya olmayabilecek kadar hızlı çalışmasına neden olur. Karşılaştırmak için kullandığım android cihazlarda karşılaştırmak için klavyeyi otomatik olarak bu ciltleme işlemini gerçekleştirir etmez. Benim iyiliğim için, iOS cihazlarda aşağıdaki şekilde hiçbir şey yapmamak için başka bir bağ oluşturdum.

ko.bindingHandlers.hasNonIosSelectedFocus = { 
    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
     if (navigator.userAgent.match(/iPad/i) == null && navigator.platform.indexOf("iPhone") == -1 && navigator.platform.indexOf("iPod") == -1) { 
      ko.bindingHandlers['hasSelectedFocus'].init(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext); 
     } 
    }, 
    update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
     if (navigator.userAgent.match(/iPad/i) == null && navigator.platform.indexOf("iPhone") == -1 && navigator.platform.indexOf("iPod") == -1) { 
      ko.bindingHandlers['hasSelectedFocus'].update(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext); 
     } 
    } 
}; 

Tl; dr: Bu kullanabilir ve tabletler hitap etmek istiyorsanız

/akıllı telefonlar sonra bu aslında beklemek etkileşim mantığı olduğunu test etmek için emin olun.

İlgili konular