2016-10-30 56 views
0

我正在學習knockout.js。我做了one example earlier,而我試圖以兩種方式修改:如何綁定模型以敲除模型不是頂級對象?

  1. 我組織了代碼,所以還有的window對象中只有一個頂級對象,以儘量減少全球範圍內,我把一切,包括我在那裏模型。

  2. 我想看看如果模型不是可觀察的,模型更改時text:綁定是否會更改視圖。爲了更好地闡述這個想法,請參閱下面HTML代碼中的註釋。

然而,當我運行這段代碼,我得到了ReferenceError: friend is not defined.

我猜想那是因爲事實證明我的model對象不再是window對象的頂級成員。

是否有可能有這樣的模型層次結構,並使其與淘汰賽一起工作?

1a.html

<html> 
    <head> 
     <meta charset="utf-8"/> 
     <script type='text/javascript' src='knockout-3.4.0.js'></script> 
    </head> 

    <!-- The purpose of this program is to find out whether just a 
     text: binding also changes the display/view if the model changes. 
     Meaning if I explicitly do not create an observable out of a model property 
     and use only a text: binding, does the property still behave like an observable? 

     To do this, I am using the same code as 1.html and 1.js, 
     except for one change. I am adding another set of textboxes 
     in which I will type in a new first name and last name. 
     Then, I will click the "Update Name" button 
     in whose listener, I will update the model properties friend.firstName 
     and friend.lastName. 

     Then, I'd like to see if the text box values for txtFirstName and txtLastName 
     change. 
     --> 
    <body> 

     <form id = "frm" name = "frm"> 
      <fieldset> 
       <legend>Your friend's basic information:</legend> 

       <div> 
        <label for = "FirstName">First Name</label> 
        <input type = "text" name = "FirstName" id = "txtFirstName" data-bind = "value: friend.firstName" /> 
       </div> 

       <div> 
        <label for = "LastName">Last Name</label> 
        <input type = "text" name = "LastName" id = "txtLastName" data-bind = "value: friend.lastName" /> 
       </div> 


        <fieldset> 
         <legend>New Information:</legend> 

         <div> 
          <label for = "NewFirstName">New Value for First Name</label> 
          <input type = "text" name = "NewFirstName" id = "txtNewFirstName" /> 
         </div> 

         <div> 
          <label for = "NewLastName">New Value for Last Name</label> 
          <input type = "text" name = "NewLastName" id = "txtNewLastName" /> 
         </div> 
        </fieldset> 

       <div> 
        <input type = "button" value = "Update Name" id = "btnUpdateName" name = "Save" /> 
       </div> 
      </fieldset> 

     </form> 

     <script type='text/javascript' src='1a.js'></script> 
    </body> 
</html> 

1a.js

var ThisDocument = function() 
{ 
    this.model = 
    { 
     friend : 
     { 
      firstName : 'Sathyaish', 
      lastName : 'Chakravarthy' 
     } 
    }; 

    this.init = function() 
    { 
     wire(window, "load", wireElementHandlers); 
    }; 

    function wire(element, eventName, listener) 
    { 
     var ie = document.all ? true : false; 

     if (!element) throw new Error("Element " + element + " not found."); 

     if (ie) 
     { 
      element.attachEvent("on" + eventName, listener); 
     } 
     else 
     { 
      element.addEventListener(eventName, listener, false); 
     } 
    }; 


    function wireElementHandlers() 
    { 
     var btnUpdateName = document.getElementById('btnUpdateName'); 
     wire(btnUpdateName, "click", changeName); 

     ko.applyBindings(this.model); 
    }; 

    function changeName(event) 
    { 
     var firstName = document.getElementById('txtNewFirstName').value; 
     var lastName = document.getElementById('txtNewLastName').value; 

     this.model.friend.firstName = firstName; 
     this.model.friend.lastName = lastName; 
    }; 
}; 

var thisDocument = new ThisDocument(); 
thisDocument.init(); 

製作模型中的頂層對象窗口內部

但是,如果我做該模型是中的頂級成員對象,代碼工作正常,我知道上面的HTML註釋和上面的第2點中所述的問題的答案。

答案是:不。如果沒有可觀察的情況,簡單的text:綁定不會在模型更改時更新視圖。

這裏是與模型作爲頂層對象的代碼:

1a.js

this.model = 
{ 
    friend : 
    { 
     firstName : 'Sathyaish', 
     lastName : 'Chakravarthy' 
    } 
}; 

var ThisDocument = function() 
{ 
    this.init = function() 
    { 
     wire(window, "load", wireElementHandlers); 
    }; 

    function wire(element, eventName, listener) 
    { 
     var ie = document.all ? true : false; 

     if (!element) throw new Error("Element " + element + " not found."); 

     if (ie) 
     { 
      element.attachEvent("on" + eventName, listener); 
     } 
     else 
     { 
      element.addEventListener(eventName, listener, false); 
     } 
    }; 


    function wireElementHandlers() 
    { 
     var btnUpdateName = document.getElementById('btnUpdateName'); 
     wire(btnUpdateName, "click", changeName); 

     ko.applyBindings(model); 
    }; 

    function changeName(event) 
    { 
     var firstName = document.getElementById('txtNewFirstName').value; 
     var lastName = document.getElementById('txtNewLastName').value; 

     model.friend.firstName = firstName; 
     model.friend.lastName = lastName; 
    }; 
}; 

var thisDocument = new ThisDocument(); 
thisDocument.init(); 

因此,我的懷疑是,this指針被弄亂了。

applyBindings方法是否存在重載,或者如果不是允許我在綁定模型時告訴knockout使用特定對象作爲this參數的重載,可能是另一種方式?

例如,

var MyDocument = function() 
{ 
    var model = 
    { 
    friend : { firstName: 'Sathyaish', lastName: 'Chakravarthy' } 
    }; 

    this.init : function() 
    { 
    ko.applyBindings(this.model /*, but this may lead knockout 
    to not be able to discover my model, as my experience so far 
    shows. I need to recalibrate the 'this' pointer so knockout 
    knows to look for the model object inside whatever I tell it to, 
    i.e. inside an instance of the MyDocument class and not inside 
    whatever the this pointer happens to reference when knockout 
    is performing the binding. */); 
    }; 
} 

var myDocument = new MyDocument(); 
myDocument.init(); 

回答

0

我覺得你真的需要映射插件和改變/放值將需要做:

model.friend.firstName(firstName) 

稍後我會嘗試你的代碼,如果有必要,我會編輯我的答案。