2012-08-10 39 views
14

hết sự tò mò và để tăng kiến ​​thức của tôi, tôi muốn triển khai một số loại ràng buộc dữ liệu hai chiều giữa các phần tử dom và biến javascript.Đồng bộ Javascript hai chiều Ràng buộc dữ liệu

Tôi đã may mắn tìm được câu trả lời tuyệt vời cho một nửa vấn đề của tôi ở đây @ stackoverflow dẫn tôi đến gist https://gist.github.com/384583, nhưng tôi vẫn không thể hoàn thành công việc ở mức 100%.

Dưới đây là một ví dụ mã của tôi: http://jsfiddle.net/bpH6Z/

Nếu bạn cố gắng chạy fiddle và bấm vào "xem giá trị gia tăng" bạn sẽ nhận được không xác định, trong khi tôi muốn có được giá trị thực tế của thuộc tính của đối tượng.

Tôi có thể làm điều gì đó sai do thiếu kinh nghiệm với javascript, nhưng bạn có biết tại sao tôi không thể đọc đúng thuộc tính 'bí mật' sau các cuộc gọi _bind() và _watch() không?

KHUYẾN CÁO: như tôi đã nói, tôi đang làm điều này vì tôi muốn có kiến ​​thức tốt hơn về javascript và tôi sẽ không viết khung của tôi. Vì vậy, bất kỳ "USE FRAMEWORK X" là hoàn toàn vô ích, như tôi có thể nhận được công việc làm với angularjs.

+0

+1 cho JS đồng bằng;) – metadings

+0

ist $ đề cập đến jQuery? Vì vậy, nó không phải là đồng bằng JS huh – daslicht

+0

Có thể trùng lặp của [Làm thế nào để thực hiện DOM ràng buộc dữ liệu trong JavaScript] (http://stackoverflow.com/questions/16483560/how-to-implement-dom-data-binding-in-javascript) – Beginner

Trả lời

5

Vui lòng thử http://jsfiddle.net/bpH6Z/4/

Tôi đã cập nhật getter định nghĩa lại bạn/setter trong Object.prototype .__ xem, cũng hiện xử lý của bạn cần phải trả lại giá trị mới.

Cập nhật: Trình xử lý của bạn không bắt buộc phải trả lại giá trị mới được đặt.

đang hiện tại:

//Got this great piece of code from https://gist.github.com/384583 
Object.defineProperty(Object.prototype, "__watch", { 
    enumerable: false, 
    configurable: true, 
    writable: false, 
    value: function(prop, handler) { 
     var val = this[prop], 
      getter = function() { 
       return val; 
      }, 
      setter = function(newval) { 
       val = newval; 
       handler.call(this, prop, newval); 
       return newval; 
      }; 

     if (delete this[prop]) { // can't watch constants 
      Object.defineProperty(this, prop, { 
       get: getter, 
       set: setter, 
       enumerable: true, 
       configurable: true 
      }); 
     } 
    } 
}); 

var Controller = function() { 
    //The property is changed whenever the dom element changes value 
    //TODO add a callback ? 
    this._bind = function (DOMelement, propertyName) { 
     //The next line is commented because priority is given to the model 
     //this[propertyName] = $(DOMelement).val(); 
     var _ctrl = this; 
     $(DOMelement).on("change input propertyChange", function(e) { 
      e.preventDefault(); 
      _ctrl[propertyName] = DOMelement.val(); 
     }); 

    }; 

    //The dom element changes values when the propertyName is setted 
    this._watch = function(DOMelement, propertyName) { 
     //__watch triggers when the property changes 
     this.__watch(propertyName, function(property, value) { 
      $(DOMelement).val(value); 
     }); 
    }; 
}; 

var ctrl = new Controller(); 
ctrl.secret = 'null'; 
ctrl._bind($('#text1'), 'secret'); // I want the model to reflect changes in #text1 
ctrl._watch($('#text2'), 'secret'); // I want the dom element #text2 to reflect changes in the model 
$('#button1').click(function() { 
    $('#output').html('Secret is : ' + ctrl.secret); //This gives problems 
}); 

HTML hiện tại:

<html> 
<head></head> 
<body> 
    value: <input type="text" id="text1" /><br /> 
    copy: <input type="text" id="text2" /><br /> 
    <input type="button" id="button1" value="View value"><br /> 
    <span id="output"></span> 
</body> 
</html> 
+0

+1 cho việc làm lại – fatmatto

+0

Điều này có làm việc với IE8 khi defineProperty chỉ hoạt động trên các đối tượng DOM không? – Integralist

+0

@Integralist rất có thể không, nhưng bạn nên thử - phải khởi động lại để xp – metadings

3

Trình xử lý bạn chuyển đến hàm __watch của bạn thiếu câu lệnh return.

this._watch = function(DOMelement, propertyName) { 
    //__watch triggers when the property changes 
    this.__watch(propertyName, function(property, value) { 
     $(DOMelement).val(value); 
     return value; 
    }) 

} 

newval được thiết lập với những gì đang trở về từ xử lý, nó sẽ được undefined mà không có.

+0

+1. Spot on, beat me to it ... Tôi chỉ nhận thấy điều này cuối cùng quá –

+0

+1 để loại bỏ nhức đầu của tôi – fatmatto

0

tôi đã tăng cường nó cho nhiều người xem.

http://jsfiddle.net/liyuankui/54vE4/

//The dom element changes values when the propertyName is setted 
this._watch = function(DOMelement, propertyName) { 
    //__watch triggers when the property changes 
    if(watchList.indexOf(DOMelement)<0){ 
     watchList.push(DOMelement); 
    } 
    this.__watch(propertyName, function(property, value) { 
     for(var i=0;i<watchList.length;i++){ 
      var watch=watchList[i]; 
      $(watch).val(value); 
      $(watch).html(value); 
     } 
    }); 
}; 
Các vấn đề liên quan