2012-06-07 30 views
5

Tôi đã cố tạo một trình quản lý ràng buộc tùy chỉnh mà tôi có thể sử dụng để cung cấp cho hành vi watermark đối với các trường nhập văn bản.watermark đầu vào văn bản bằng cách sử dụng tùy chỉnh bindingHandler

By watermark tôi có nghĩa là: để thêm giá trị mặc định cho các trường văn bản được loại bỏ trên tập trung, và thay thế vào mờ nếu trường văn bản vẫn còn trống

tôi đã quản lý để có được điều này để làm việc như thể hiện trong jsfiddle này : http://jsfiddle.net/rpallas/nvxuw/

tôi có 3 câu hỏi về giải pháp này:

  1. có cách nào để thay đổi nó vì vậy mà tôi chỉ phải kê khai giá trị watermark một lần? Hiện tại tôi phải đặt nó vào vị trí mà tôi khai báo ràng buộc và tôi cũng phải khởi tạo quan sát có cùng giá trị trong viewModel - vì nó sẽ không có giá trị ban đầu.
  2. Có cách nào tốt hơn để đến được cơ sở có thể quan sát thấy rằng giá trị của phần tử được ràng buộc hay không. Tôi hiện đang lấy nó bằng cách sử dụng allBindingsAccessor, nhưng điều này cảm thấy sai với tôi. Ban đầu tôi đã chỉ thiết lập giá trị bằng cách sử dụng jquery $(element).val('') nhưng điều này cũng cảm thấy sai. Điều gì là tốt nhất, hoặc là có một cách tốt hơn?
  3. Có ai có hoặc biết giải pháp hiện tại cho vấn đề này không? Tôi có phát minh lại bánh xe không?

Trả lời

14

Tôi nghĩ rằng bạn đang sử dụng allbindings là không cần thiết. Trong thực tế, tôi không nghĩ rằng watermark cần phải được nhận thức của các quan sát ở tất cả vì đó là những gì một watermark thường làm i.e các thuộc tính placeholder.

Điều này có phù hợp với bạn không?

ko.bindingHandlers.watermark = { 
    init: function (element, valueAccessor, allBindingsAccessor) { 
     var value = valueAccessor(), allBindings = allBindingsAccessor(); 
     var defaultWatermark = ko.utils.unwrapObservable(value); 
     var $element = $(element); 

     setTimeout(function() { 
      $element.val(defaultWatermark);}, 0); 

     $element.focus(
      function() { 
       if ($element.val() === defaultWatermark) { 
        $element.val(""); 
       } 
      }).blur(function() { 
       if ($element.val() === '') { 
        $element.val(defaultWatermark) 
       } 
      }); 
    } 
}; 

http://jsfiddle.net/madcapnmckay/Q5yME/1/

Hope this helps.

+1

vâng, đó gần như chính xác những gì tôi đã có trước khi tôi thay đổi nó để sử dụng allBindingsAccessor. Tôi đã thiếu 'setTimeout' khi cố thiết lập giá trị ban đầu. Bạn có thể giải thích ngắn gọn tại sao điều đó là bắt buộc? Ngoài ra, bạn có biết nếu có một cách tốt hơn? hoặc bạn có nghĩ rằng đây là một cách tốt (đủ) (về toàn bộ giải pháp)? Ví dụ tôi nhận thấy rằng có một ràng buộc hasfocus (được xây dựng trong). Đó có thể là một cách tiếp cận tốt hơn? – Robbie

+2

Tôi nghĩ rằng cách tiếp cận này là tốt nếu bạn muốn hỗ trợ các trình duyệt cũ hơn. Đối với những cái mới chỉ sử dụng thuộc tính giữ chỗ. SetTimeout là cần thiết bởi vì nội bộ KO sử dụng một setTimeout trước khi thiết lập giá trị của đầu vào. Điều này có nghĩa là mã của bạn đã chạy trước khi mã KO thiết lập giá trị do đó bạn cần setTimeout để một lần nữa đảm bảo mã của bạn đến cuối cùng trong quá trình thực hiện. – madcapnmckay

+0

Cảm ơn rất nhiều vì đã giải thích và giúp đỡ. – Robbie

1

Cách tiếp cận trước là tốt miễn là logic ứng dụng của bạn thực sự đơn giản, hãy lưu ý rằng giải pháp gây rối với các giá trị của Mô hình xem của bạn, các giá trị đó có thể quan sát được và họ có thể đăng ký hoặc tính toán liên kết với nó bằng cách thay đổi giá trị bạn thay đổi Kiểu xem của bạn. Đây là một giải pháp khác mà không cần cập nhật Mô hình Xem của bạn

ko.bindingHandlers.fakePlaceHolderWhenNeedIt = { 
    init: function (element, valueAccessor, allBindings, vm) { 
    if (!Modernizr.input.placeholder) { 
     var placeHolderVal = $(element).attr("placeholder"); 

     if (placeHolderVal != null || placeHolderVal != '') { 

      var $element = $(element); 
      var value = valueAccessor() 
      var valueUnwrapped = ko.utils.unwrapObservable(value); 


      $element.keyup(function() { 
       var inputValue = $(this).val(); 
       var $watermark = $(this).prev('.ie-placeholder'); 
       if (inputValue == null || inputValue == '') { 
        $watermark.show(); 
       } 
       else { 
        $watermark.hide(); 
       } 
      }); 

      var display = valueUnwrapped != null || valueUnwrapped != '' ? "block" : "none"; 
      var left = $element.position().left; 
      var top = $element.position().top; 
      var paddingLeft = $element.css('padding-left'); 
      var paddingRight = $element.css('padding-right'); 
      var paddingTop = $element.css('padding-top'); 
      var paddingBottom = $element.css('padding-bottom'); 

      var height = $element.css('height'); 
      var placeHolder = '<div class="ie-placeholder" style="position:absolute;left:' + left + ';top:' + top + ';padding-top: ' + paddingTop + ';padding-bottom: ' + paddingBottom + ';padding-left: ' + paddingLeft + ';padding-right: ' + paddingRight + ';height: ' + height + ';line-height:' + height + ';display:' + display + ';">' + placeHolderVal + '</div>'; 

      $(placeHolder).click(function() { $element.focus(); }).insertBefore(element); 
     } 
    } 
}, 
update: function (element, valueAccessor, allBindings, vm) { 
    if (!Modernizr.input.placeholder) { 
     var placeHolderVal = $(element).attr("placeholder"); 

     if (placeHolderVal != null || placeHolderVal != '') { 
      var $element = $(element); 
      var value = valueAccessor() 
      var valueUnwrapped = ko.utils.unwrapObservable(value); 

      var $watermark = $element.prev('.ie-placeholder'); 
      if (valueUnwrapped == null || valueUnwrapped == '') { 
       $watermark.show(); 
      } 
      else { 
       $watermark.hide(); 
      } 
     } 
    } 
} 
Các vấn đề liên quan