<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                ## 1?? Contacts editor 這個例子和微軟為演示jQuery Data Linking Proposal例子提供的例子一樣的提供的,我們可以看看Knockout實現是難了還是容易了。 代碼量的多少不重要(盡快Knockout 的實現很簡潔),重要的看起來是否容易理解且可讀。查看HTML源代碼,看看如何實現的view model以及綁定的。 ?![](https://box.kancloud.cn/2015-11-22_5651b1672eabd.png) **代碼: View** ~~~ <h2>Contacts</h2> <div id="contactsList" data-bind='template: "contactsListTemplate"'> </div> <script type="text/html" id="contactsListTemplate"> <table class='contactsEditor'> <tr> <th>First name</th> <th>Last name</th> <th>Phone numbers</th> </tr> {{each(i, contact) contacts()}} <tr> <td> <input data-bind="value: firstName"/> <div><a href="#" data-bind="click: function() { viewModel.removeContact(contact) }">Delete</a></div> </td> <td><input data-bind="value: lastName"/></td> <td> <table> {{each(i, phone) phones}} <tr> <td><input data-bind="value: type"/></td> <td><input data-bind="value: number"/></td> <td><a href="#" data-bind="click: function() { viewModel.removePhone(contact, phone) }">Delete</a></td> </tr> {{/each}} </table> <a href="#" data-bind="click: function() { viewModel.addPhone(contact) }">Add number</a> </td> </tr> {{/each}} </table> </script> <p> <button data-bind="click: addContact"> Add a contact</button> <button data-bind="click: save, enable: contacts().length > 0"> Save to JSON</button> </p> <textarea data-bind="value: lastSavedJson" rows="5" cols="60" disabled="disabled"> </textarea> ~~~ **代碼: View model** ~~~ var viewModel = { contacts: new ko.observableArray([ { firstName: "Danny", lastName: "LaRusso", phones: [ { type: "Mobile", number: "(555) 121-2121" }, { type: "Home", number: "(555) 123-4567"}] }, { firstName: "Sensei", lastName: "Miyagi", phones: [ { type: "Mobile", number: "(555) 444-2222" }, { type: "Home", number: "(555) 999-1212"}] } ]), addContact: function () { viewModel.contacts.push({ firstName: "", lastName: "", phones: [] }); }, removeContact: function (contact) { viewModel.contacts.remove(contact); }, addPhone: function (contact) { contact.phones.push({ type: "", number: "" }); viewModel.contacts.valueHasMutated(); }, removePhone: function (contact, phone) { ko.utils.arrayRemoveItem(contact.phones, phone); viewModel.contacts.valueHasMutated(); }, save: function () { viewModel.lastSavedJson(JSON.stringify(viewModel.contacts(), null, 2)); }, lastSavedJson: new ko.observable("") }; ko.applyBindings(viewModel); ~~~ ## 2?? Editable grid 該例是使用“foreach”綁定為數組里的每一項來render到 template上。好處(相對于模板內部使用for循環)是當你添加或者刪除item項的時候,Knockout不需要重新render – 只需要render新的item項。就是說UI上其它控件的狀態(比如驗證狀態)不會丟失。 如何一步一步構建這個例子并集成ASP.NET MVC,請[參閱此貼](http://blog.stevensanderson.com/2010/07/12/editing-a-variable-length-list-knockout-style/)。 ?![](https://box.kancloud.cn/2015-11-22_5651b1674b5d7.png) **代碼: View** ~~~ <form action="/someServerSideHandler"> <p> You have asked for <span data-bind="text: gifts().length">&nbsp;</span> gift(s)</p> <table data-bind="visible: gifts().length > 0"> <thead> <tr> <th>Gift name</th> <th>Price</th> <th></th> </tr> </thead> <tbody data-bind='template: { name: "giftRowTemplate", foreach: gifts }'> </tbody> </table> <button data-bind="click: addGift"> Add Gift</button> <button data-bind="enable: gifts().length > 0" type="submit"> Submit</button> </form> <script type="text/html" id="giftRowTemplate"> <tr> <td><input class="required" data-bind="value: name, uniqueName: true"/></td> <td><input class="required number" data-bind="value: price, uniqueName: true"/></td> <td><a href="#" data-bind="click: function() { viewModel.removeGift($data) }">Delete</a></td> </tr> </script> ~~~ **代碼: View model** ~~~ var viewModel = { gifts: ko.observableArray([ { name: "Tall Hat", price: "39.95" }, { name: "Long Cloak", price: "120.00" } ]), addGift: function () { this.gifts.push({ name: "", price: "" }); }, removeGift: function (gift) { this.gifts.remove(gift); }, save: function (form) { alert("Could now transmit to server: " + ko.utils.stringifyJson(this.gifts)); // To transmit to server, write this: ko.utils.postJson($("form")[0], this.gifts); } }; ko.applyBindings(viewModel); $("form").validate({ submitHandler: function () { viewModel.save() } }); ~~~ ## 3?? Shopping cart screen 這個例子展示的是依賴監控屬性(dependent observable)怎么樣鏈在一起。每個cart對象都有一個dependentObservable對象去計算自己的subtotal,這些又被一個進一步的dependentObservable對象依賴計算總的價格。當改變數據的時候,整個鏈上的依賴監控屬性都會改變,所有相關的UI元素也會被更新。 這個例子也展示了如何創建聯動的下拉菜單。 ![](https://box.kancloud.cn/2015-11-22_5651b167624be.png) **代碼: View** ~~~ <div id="cartEditor"> <table width="100%"> <thead> <tr> <th width="25%">Category</th> <th width="25%">Product</th> <th width="15%" class='price'>Price</th> <th width="10%" class='quantity'>Quantity</th> <th width="15%" class='price'>Subtotal</th> <th width="10%"></th> </tr> </thead> <tbody data-bind='template: {name: "cartRowTemplate", foreach: lines}'> </tbody> </table> <p class="grandTotal"> Total value: <span data-bind="text: formatCurrency(grandTotal())"></span> </p> <button data-bind="click: addLine"> Add product</button> <button data-bind="click: save"> Submit order</button> </div> <script type="text/html" id="cartRowTemplate"> <tr> <td><select data-bind='options: sampleProductCategories, optionsText: "name", optionsCaption: "Select...", value: category'></select></td> <td><select data-bind='visible: category, options: category() ? category().products : null, optionsText: "name", optionsCaption: "Select...", value: product'></select></td> <td class='price'><span data-bind='text: product() ? formatCurrency(product().price) : ""'></span></td> <td class='quantity'><input data-bind='visible: product, value: quantity, valueUpdate: "afterkeydown"'/></td> <td class='price'><span data-bind='visible: product, text: formatCurrency(subtotal())'></span></td> <td><a href="#" data-bind='click: function() { cartViewModel.removeLine($data) }'>Remove</a></td> </tr> </script> ~~~ **代碼: View model** ~~~ function formatCurrency(value) { return "$" + value.toFixed(2); } var cartLine = function () { this.category = ko.observable(); this.product = ko.observable(); this.quantity = ko.observable(1); this.subtotal = ko.dependentObservable(function () { return this.product() ? this.product().price * parseInt("0" + this.quantity(), 10) : 0; } .bind(this)); // Whenever the category changes, reset the product selection this.category.subscribe(function () { this.product(undefined); } .bind(this)); }; var cart = function () { // Stores an array of lines, and from these, can work out the grandTotal this.lines = ko.observableArray([new cartLine()]); // Put one line in by default this.grandTotal = ko.dependentObservable(function () { var total = 0; for (var i = 0; i < this.lines().length; i++) total += this.lines()[i].subtotal(); return total; } .bind(this)); // Operations this.addLine = function () { this.lines.push(new cartLine()) }; this.removeLine = function (line) { this.lines.remove(line) }; this.save = function () { var dataToSave = $.map(this.lines(), function (line) { return line.product() ? { productName: line.product().name, quantity: line.quantity()} : undefined }); alert("Could now send this to server: " + JSON.stringify(dataToSave)); }; }; var cartViewModel = new cart(); ko.applyBindings(cartViewModel, document.getElementById("cartEditor")); ~~~ ## 4?? Twitter client 這是一個復雜的例子,展示了幾乎所有Knockout特性來構建一個富客戶端。 用戶數據存在一個JavaScript模型里,通過模板來展示。就是說我們可以通過清理用戶列表里的數據來達到隱藏用戶信息的目的,而不需要手動去隱藏DOM元素。 按鈕將根據他們是否可操作來自動變成enabled或disabled狀態。例如,有一個叫hasUnsavedChanges的依賴監控屬性(dependentObservable)控制這“Save”按鈕的enabled狀態。 可以非常方便地從外部JSON服務獲取數據,并集成到view model里,然后顯示在頁面上。 ![](https://box.kancloud.cn/2015-11-22_5651b16774e16.png) **代碼: View** ~~~ <div class="loadingIndicator"> Loading...</div> <div class="configuration"> <div class="listChooser"> <button data-bind='click: deleteList, enable: editingList.name'> Delete</button> <button data-bind='click: saveChanges, enable: hasUnsavedChanges'> Save</button> <select data-bind='options: savedLists, optionsValue: "name", value: editingList.name'> </select> </div> <p> Currently viewing <span data-bind="text: editingList.userNames().length">&nbsp;</span> user(s):</p> <div class="currentUsers" data-bind='template: { name: "usersTemplate", data: editingList }'> </div> <form data-bind="submit: addUser"> <label> Add user:</label> <input data-bind='value: userNameToAdd, valueUpdate: "keyup", css: { invalid: !userNameToAddIsValid() }' /> <button type="submit" data-bind='enable: userNameToAddIsValid() && userNameToAdd() != ""'> Add</button> </form> </div> <div class="tweets" data-bind='template: { name: "tweetsTemplate", data: currentTweets }'> </div> <script type="text/html" id="tweetsTemplate"> <table width="100%"> {{each $data}} <tr> <td><img src="${ profile_image_url }"/></td> <td> <a class="twitterUser" href="http://twitter.com/${ from_user }">${ from_user }</a> ${ text } <div class="tweetInfo">${ created_at }</div> </td> </tr> {{/each}} </table> </script> <script type="text/html" id="usersTemplate"> <ul> {{each(i, userName) userNames()}} <li><button data-bind="click: function() { userNames.remove(userName) }">Remove</button> <div>${ userName }</div></li> {{/each}} </ul> </script> ~~~ **代碼: View model** ~~~ // The view model holds all the state we're working with. It also has methods that can edit it, and it uses // dependentObservables to compute more state in terms of the underlying data // -- // The view (i.e., the HTML UI) binds to this using data-bind attributes, so it always stays up-to-date with // the view model, even though the view model does not know or care about any view that binds to it var viewModel = { savedLists: ko.observableArray([ { name: "Celebrities", userNames: ['JohnCleese', 'MCHammer', 'StephenFry', 'algore', 'StevenSanderson'] }, { name: "Microsoft people", userNames: ['BillGates', 'shanselman', 'haacked', 'ScottGu'] }, { name: "Tech pundits", userNames: ['Scobleizer', 'LeoLaporte', 'techcrunch', 'BoingBoing', 'timoreilly', 'codinghorror'] } ]), editingList: { name: ko.observable("Tech pundits"), userNames: ko.observableArray() }, userNameToAdd: ko.observable(""), currentTweets: ko.observableArray([]) }; viewModel.findSavedList = function (name) { var lists = this.savedLists(); for (var i = 0; i < lists.length; i++) if (lists[i].name === name) return lists[i]; }; // Methods viewModel.addUser = function () { if (this.userNameToAdd() && this.userNameToAddIsValid()) { this.editingList.userNames.push(this.userNameToAdd()); this.userNameToAdd(""); } } viewModel.saveChanges = function () { var saveAs = prompt("Save as", this.editingList.name()); if (saveAs) { var dataToSave = this.editingList.userNames().slice(0); var existingSavedList = this.findSavedList(saveAs); if (existingSavedList) existingSavedList.userNames = dataToSave; // Overwrite existing list else this.savedLists.push({ name: saveAs, userNames: dataToSave }); // Add new list this.editingList.name(saveAs); } } viewModel.deleteList = function () { var nameToDelete = this.editingList.name(); var savedListsExceptOneToDelete = $.grep(this.savedLists(), function (list) { return list.name != nameToDelete }); this.editingList.name(savedListsExceptOneToDelete.length == 0 ? null : savedListsExceptOneToDelete[0].name); this.savedLists(savedListsExceptOneToDelete); }; ko.dependentObservable(function () { // Observe viewModel.editingList.name(), so when it changes (i.e., user selects a different list) we know to copy the saved list into the editing list var savedList = viewModel.findSavedList(viewModel.editingList.name()); if (savedList) { var userNamesCopy = savedList.userNames.slice(0); viewModel.editingList.userNames(userNamesCopy); } else viewModel.editingList.userNames([]); }); viewModel.hasUnsavedChanges = ko.dependentObservable(function () { if (!this.editingList.name()) return this.editingList.userNames().length > 0; var savedData = this.findSavedList(this.editingList.name()).userNames; var editingData = this.editingList.userNames(); return savedData.join("|") != editingData.join("|"); }, viewModel); viewModel.userNameToAddIsValid = ko.dependentObservable(function () { return (this.userNameToAdd() == "") || (this.userNameToAdd().match(/^\s*[a-zA-Z0-9_]{1,15}\s*$/) != null); }, viewModel); // The active user tweets are (asynchronously) computed from editingList.userNames ko.dependentObservable(function () { twitterApi.getTweetsForUsers(this.editingList.userNames(), function (data) { viewModel.currentTweets(data) }) }, viewModel); ko.applyBindings(viewModel); // Using jQuery for Ajax loading indicator - nothing to do with Knockout $(".loadingIndicator").ajaxStart(function () { $(this).fadeIn(); }) .ajaxComplete(function () { $(this).fadeOut(); }); ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看