Knockoutjs屬性綁定(Bindings)之表單處理(Working with form fields)


我們在使用Knockoutjs最多的時候莫過於使用上次介紹的流程控制(Control flow)和今天將要介紹的表單處理(Working with form fields)了,我們使用表單處理可以幫助我們處理比如事件、驗證等功能,下面我們就開始吧。

一、click binding

使用click binding可以對某一個可見的DOM元素進行事件綁定,當用戶點擊這個元素時會執行對應的方法,完成相應的功能,我們經常在button、input、a等DOM元素上進行click binding。

(1)、下面我們來看一個例子:每當我點擊Button之后,點擊次數都會加1

 1 <script type="text/javascript" src="knockout-2.2.0.js"></script>
 2 
 3 <div> 
 4     You've clicked <span data-bind="text: numberOfClicks"></span> times 
 5     <button data-bind="click: incrementClickCounter">Click me</button> 
 6 </div> 
 7   
 8 <script type="text/javascript">
 9     var viewModel = {
10         numberOfClicks: ko.observable(0),
11         incrementClickCounter: function () {
12             var previousCount = this.numberOfClicks();
13             this.numberOfClicks(previousCount + 1);
14         }
15     };
16     ko.applyBindings(viewModel);
17 </script>

 

(2)、我們也可以把當前元素作為參數傳遞給所要調用的方法,如下例子:我們點擊按鈕,然后刪除按鈕對應的元素

 1 <script type="text/javascript" src="knockout-2.2.0.js"></script>
 2 
 3 <ul data-bind="foreach: places"> 
 4     <li> 
 5         <span data-bind="text: $data"></span> 
 6         <button data-bind="click: $parent.removePlace">Remove</button> 
 7     </li> 
 8 </ul> 
 9   
10  <script type="text/javascript">
11      function MyViewModel() {
12          var self = this;
13          self.places = ko.observableArray(['London', 'Paris', 'Tokyo']);
14 
15          // The current item will be passed as the first parameter, so we know which place to remove 
16          self.removePlace = function (place) {
17              self.places.remove(place)
18          }
19      }
20      ko.applyBindings(new MyViewModel()); 
21 </script>

關於這個例子我們有以下的兩點說明:

      (a)、如果我們在一個嵌套的元素中使用click binding的話,例如我們在foreach或者with塊中使用click binding,但是此時click對應的方法在View Model的根部或者他的父上下文,此時我們需要一個前綴比如$parent或者$root來定位我們的方法。
      (b)、在我們的View Model中我們經常為我們的this起一個別名為self,這樣就會防止this指向的地方改變而導致我們程序的錯誤。

 

(3)、定義事件對象和傳遞更多的參數

     (a)、定義一個事件

 1 <button data-bind="click: myFunction"> 
 2     Click me 
 3 </button> 
 4   
 5  <script type="text/javascript"> 
 6     var viewModel = { 
 7         myFunction: function(data, event) { 
 8             if (event.shiftKey) { 
 9                 //do something different when user has shift key down 
10             } else { 
11                 //do normal action 
12             } 
13         } 
14     }; 
15     ko.applyBindings(viewModel); 
16 </script>

此時就會判斷,如果是shift 鍵點擊的話,則會執行對應的內容,否則執行其他的內容。
  (b)、傳遞更多的參數

如果我們想要傳遞很多參數給調用的方法的話,我們可以在標簽中包括對應方法要傳遞的參數等,如下:

1 <button data-bind="click: function(data, event) { myFunction('param1', 'param2', data, event) }"> 
2     Click me 
3 </button>

但是,如果我們不想要在標簽中出現這么多的內容的話,我們可以使用KO的bind方法來進行方法的傳遞,如下:

1 <button data-bind="click: myFunction.bind($data, 'param1', 'param2')"> 
2     Click me 
3 </button>


(4)、防止事件的沖突

在默認情況下,Knockoutjs允許事件綁定從一個元素傳遞到更高一級的元素。比如:一個DOM元素和他的父元素都使用了click事件,如果我們點擊其中一個則兩個事件都會執行,此時,我們就可以使用“clickBubble”來制定哪個事件不執行,如下:

1 <div data-bind="click: myDivHandler"> 
2     <button data-bind="click: myButtonHandler, clickBubble: false"> 
3         Click me 
4     </button> 
5 </div>

在默認的情況下,當點擊事件時會首先執行myButtonHandler,然后執行myDivHandler。但是當我們在button上使用的clickBubble:false時,則會跳過myButtonHandler去執行myDivHandler了。

二、event binding

我們也可以使用event binding來進行事件綁定,比如:keypress, mouseover 、 mouseout等

(1)、使用mouseover和mouseout控制是否顯示div

 1 <script type="text/javascript" src="knockout-2.2.0.js"></script>
 2 
 3 <div> 
 4     <div data-bind="event: { mouseover: enableDetails, mouseout: disableDetails }"> 
 5         Mouse over me 
 6     </div> 
 7     <div data-bind="visible: detailsEnabled"> 
 8         Details 
 9     </div> 
10 </div> 
11   
12 <script type="text/javascript">
13     var viewModel = {
14         detailsEnabled: ko.observable(false),
15         enableDetails: function () {
16             this.detailsEnabled(true);
17         },
18         disableDetails: function () {
19             this.detailsEnabled(false);
20         }
21     };
22     ko.applyBindings(viewModel); 
23 </script>

(2)、參數傳遞
當使用event binding的時候,Knockoutjs會默認將當前的Model Value作為第一個參數傳遞給事件方法。如下:

 1 <script type="text/javascript" src="knockout-2.2.0.js"></script>
 2 
 3 <ul data-bind="foreach: places"> 
 4     <li data-bind="text: $data, event: { mouseover: $parent.logMouseOver }"> </li> 
 5 </ul> 
 6 <p>You seem to be interested in: <span data-bind="text: lastInterest"> </span></p> 
 7   
 8  <script type="text/javascript">
 9      function MyViewModel() {
10          var self = this;
11          self.lastInterest = ko.observable();
12          self.places = ko.observableArray(['London', 'Paris', 'Tokyo']);
13 
14          // The current item will be passed as the first parameter, so we know which place was hovered over 
15          self.logMouseOver = function (place) {
16              self.lastInterest(place);
17          }
18      }
19      ko.applyBindings(new MyViewModel()); 
20 </script>

(3)、傳遞多個參數
在進行多個參數傳遞時,我們可以參照click binding中的多個參數傳遞,如下:

1 <div data-bind="event: { mouseover: function(data, event) { myFunction('param1', 'param2', data, event) } }"> 
2     Mouse over me 
3 </div>

我們也可以使用下面的方法進行多個參數的傳遞:

1 <button data-bind="event: { mouseover: myFunction.bind($data, 'param1', 'param2') }"> 
2     Click me 
3 </button>

(4)、同樣的在event binding中也會有事件的沖突,在click binding中我們使用clickBubble來處理,如果我們要mouseover事件的話我們可以使用mouseoverBubble來處理,如果使用mouseout的話我們可以使用mouseoutBubble來處理等等。

三、submit binding

我們可以使用submit binding進行表單的提交,但我們要注意此時並沒有將表單提交給服務器,而是提交給了我們的View Model。使用submit binding的示例如下:

 1 <form data-bind="submit: doSomething"> 
 2     ... form contents go here ... 
 3     <button type="submit">Submit</button> 
 4 </div> 
 5   
 6 <script type="text/javascript"> 
 7     var viewModel = { 
 8         doSomething : function(formElement) { 
 9             // ... now do something  
10         } 
11     }; 
12 </script>


四、enable binding

使用enable binding可以很好的控制DOM元素是否顯示等(當enable的值為true時),這對input, selecttextarea等特別的有用。下面我們來看一個例子:我們定義一個checkbox和一個text,當用戶勾選checkbox以后才能在text中輸入內容,否則不能輸入:

 1 <script type="text/javascript" src="knockout-2.2.0.js"></script>
 2 
 3 <p> 
 4     <input type='checkbox' data-bind="checked: hasCellphone" /> 
 5     I have a cellphone 
 6 </p> 
 7 <p> 
 8     Your cellphone number: 
 9     <input type='text' data-bind="value: cellphoneNumber, enable: hasCellphone" /> 
10 </p> 
11   
12 <script type="text/javascript">
13     var viewModel = {
14         hasCellphone: ko.observable(false),
15         cellphoneNumber: ""
16     };
17     ko.applyBindings(viewModel);
18 </script>


五、disable binding

disable binding的使用方法和enable binding的使用方法一樣,只是判斷條件相反。

 

六、value binding

我們可以使用value binding為DOM元素設置默認值,比如:我們使用value為其設置默認的用戶名和密碼

 1 <script type="text/javascript" src="knockout-2.2.0.js"></script>
 2 
 3 <p>Login name: <input data-bind="value: userName" /></p> 
 4 <p>Password: <input type="password" data-bind="value: userPassword" /></p> 
 5   
 6 <script type="text/javascript"> 
 7     var viewModel = { 
 8         userName: ko.observable("123456"),        // Initially blank 
 9         userPassword: ko.observable("abc"), // Prepopulate 
10     }; 
11     ko.applyBindings(viewModel);
12 </script>


七、hasfocus binding

在使用hasfocus binding時,我們可以通過View Model層為一個元素設置true和false來控制hasfocus,也可以在View層對某一個元素進行綁定。

例1:當input獲得焦點時則會顯示相應的文本

 1 <script type="text/javascript" src="knockout-2.2.0.js"></script>
 2 
 3 <input data-bind="hasfocus: isSelected" /> 
 4 <button data-bind="click: setIsSelected">Focus programmatically</button> 
 5 <span data-bind="visible: isSelected">The textbox has focus</span>
 6   
 7 <script type="text/javascript">
 8     var viewModel = {
 9         isSelected: ko.observable(false),
10         setIsSelected: function () { this.isSelected(true) }
11     };
12     ko.applyBindings(viewModel); 
13 </script>

例2:點擊文本后即可進行編輯

 1 <script type="text/javascript" src="knockout-2.2.0.js"></script>
 2 
 3 <p> 
 4     Name:  
 5     <b data-bind="visible: !editing(), text: name, click: edit">&nbsp;</b> 
 6     <input data-bind="visible: editing, value: name, hasfocus: editing" /> 
 7 </p> 
 8 <p><em>Click the name to edit it; click elsewhere to apply changes.</em></p>
 9   
10 <script type="text/javascript">
11     function PersonViewModel(name) {
12         // Data 
13         this.name = ko.observable(name);
14         this.editing = ko.observable(false);
15 
16         // Behaviors 
17         this.edit = function () { this.editing(true) }
18     }
19 
20     ko.applyBindings(new PersonViewModel("Bert Bertington"));
21 </script>


八、checked binding

(1)、checkbox使用

 1 <p>Send me spam: <input type="checkbox" data-bind="checked: wantsSpam" /></p> 
 2 <div data-bind="visible: wantsSpam"> 
 3     Preferred flavors of spam: 
 4     <div><input type="checkbox" value="cherry" data-bind="checked: spamFlavors" /> Cherry</div> 
 5     <div><input type="checkbox" value="almond" data-bind="checked: spamFlavors" /> Almond</div> 
 6     <div><input type="checkbox" value="msg" data-bind="checked: spamFlavors" /> Monosodium Glutamate</div> 
 7 </div> 
 8   
 9 <script type="text/javascript"> 
10     var viewModel = { 
11         wantsSpam: ko.observable(true), 
12         spamFlavors: ko.observableArray(["cherry","almond"]) // Initially checks the Cherry and Almond checkboxes 
13     }; 
14       
15     // ... then later ... 
16     viewModel.spamFlavors.push("msg"); // Now additionally checks the Monosodium Glutamate checkbox 
17 </script>


(2)、radio使用

 1 <p>Send me spam: <input type="checkbox" data-bind="checked: wantsSpam" /></p> 
 2 <div data-bind="visible: wantsSpam"> 
 3     Preferred flavor of spam: 
 4     <div><input type="radio" name="flavorGroup" value="cherry" data-bind="checked: spamFlavor" /> Cherry</div> 
 5     <div><input type="radio" name="flavorGroup" value="almond" data-bind="checked: spamFlavor" /> Almond</div> 
 6     <div><input type="radio" name="flavorGroup" value="msg" data-bind="checked: spamFlavor" /> Monosodium Glutamate</div> 
 7 </div> 
 8   
 9 <script type="text/javascript"> 
10     var viewModel = { 
11         wantsSpam: ko.observable(true), 
12         spamFlavor: ko.observable("almond") // Initially selects only the Almond radio button 
13     }; 
14       
15     // ... then later ... 
16     viewModel.spamFlavor("msg"); // Now only Monosodium Glutamate is checked 
17 </script>


九、options binding

使用options binding可以實現我們的下拉列表框,下面我們看幾個例子:

(1)、一個簡單的下拉列表

 1 <script type="text/javascript" src="knockout-2.2.0.js"></script>
 2 
 3 <p>Destination country: <select data-bind="options: availableCountries"></select></p> 
 4   
 5 <script type="text/javascript">
 6     var viewModel = {
 7         availableCountries: ko.observableArray(['France', 'Germany', 'Spain']) // These are the initial options 
 8     };
 9 
10     // ... then later ... 
11     viewModel.availableCountries.push('China'); // Adds another option
12     ko.applyBindings(viewModel);
13 </script>

(2)、多選列表框

 1 <script type="text/javascript" src="knockout-2.2.0.js"></script>
 2 
 3 <p>Destination country: <select data-bind="options: availableCountries" size="5" multiple="true"></select></p> 
 4   
 5 <script type="text/javascript">
 6     var viewModel = {
 7         availableCountries: ko.observableArray(['France', 'Germany', 'Spain']) // These are the initial options 
 8     };
 9 
10     // ... then later ... 
11     viewModel.availableCountries.push('China'); // Adds another option
12     ko.applyBindings(viewModel);
13 </script>

(3)、使用JavaScript對象來作為下拉列表的內容

 1 <script type="text/javascript" src="knockout-2.2.0.js"></script>
 2 
 3 <p> 
 4     Your country:  
 5     <select data-bind="options: availableCountries, optionsText: 'countryName', value: selectedCountry, optionsCaption: 'Choose...'"></select> 
 6 </p> 
 7   
 8 <div data-bind="visible: selectedCountry"> <!-- Appears when you select something --> 
 9     You have chosen a country with population  
10     <span data-bind="text: selectedCountry() ? selectedCountry().countryPopulation : 'unknown'"></span>. 
11 </div> 
12   
13 <script type="text/javascript">
14     // Constructor for an object with two properties 
15     var Country = function (name, population) {
16         this.countryName = name;
17         this.countryPopulation = population;
18     };
19 
20     var viewModel = {
21         availableCountries: ko.observableArray([
22             new Country("UK", 65000000),
23             new Country("USA", 320000000),
24             new Country("Sweden", 29000000)
25         ]),
26         selectedCountry: ko.observable() // Nothing selected by default 
27     };
28     ko.applyBindings(viewModel);
29 </script>


十、selectedOptions binding

實現多選列表框的默認選中,例:

 1 <script type="text/javascript" src="knockout-2.2.0.js"></script>
 2 
 3 <p> 
 4     Choose some countries you'd like to visit:  
 5     <select data-bind="options: availableCountries, selectedOptions: chosenCountries" size="5" multiple="true"></select> 
 6 </p> 
 7   
 8 <script type="text/javascript">
 9     var viewModel = {
10         availableCountries: ko.observableArray(['France', 'Germany', 'Spain']),
11         chosenCountries: ko.observableArray(['Germany']) // Initially, only Germany is selected 
12     };
13 
14     // ... then later ... 
15     viewModel.chosenCountries.push('France'); // Now France is selected too
16     ko.applyBindings(viewModel);
17 </script>

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM