MVC中利用knockout.js實現動態uniqueId


題目比較拗口,但是這篇文章確實直說這一點。

knockout.js是一個JS庫,它的官網是http://knockoutjs.com/

 

這篇文章的重點是knockout在工作的一個功能中的應用。最終效果圖如下:

QQ圖片20140325141848

 

點擊Add Other Source UI添加一個空行

現有行可以直接修改

點擊delete                  UI刪除當前行

點擊保存時數據才會錄入到服務器

 

Html代碼如下

<div class="row">
                    <span class="label">Information from other sources:</span>
                    <table class="inline-dataTable">
                        <thead>
                            <tr>
                                <td>
                                    Test
                                </td>
                                <td>
                                    Date
                                </td>
                                <td>
                                    Scores
                                </td>
                                <td>
                                    Action
                                </td>
                            </tr>
                        </thead>
                        <tbody data-bind="foreach: OtherSources">
                            <tr>
                                <td>
                                    <input required="required" class="required" data-bind="value: Test, uniqueName: true, uniqueId: Test" /><span
                                        class="field-validation-valid" data-bind="valmsg: true" data-valmsg-replace="true" />
                                </td>
                                <td>
                                    <input id="Date" class="Date required noFutureDate" required="required" data-bind="value: Date, uniqueName: true, dateName: true, uniqueId: Date" /><span
                                        class="field-validation-valid" data-bind="valmsg: true" data-valmsg-replace="true" />
                                </td>
                                <td>
                                    <input required="required" class="required number" data-bind="value: Scores, uniqueName: true, uniqueId: Scores" /><span
                                        class="field-validation-valid" data-bind="valmsg: true" data-valmsg-replace="true" />
                                </td>
                                <td>
                                    <a href="#" data-bind="click: function(){ viewModel.removeOtherSource($data) } ">delete</a>
                                </td>
                            </tr>
                        </tbody>
                    </table>
                    <div class="add-button">
                        <a href="#" id="ButtonAddOtherSource" data-bind="click: addOtherSource">Add Other Source</a>
                    </div>
                </div>

Js代碼如下:

 $(document).ready(function () {
            // NOTE: KnockoutJS unique id generator (http://stackoverflow.com/questions/9233176/unique-ids-in-knockout-js-templates)
            ko.bindingHandlers.uniqueId = {
                init: function (element, valueAccessor) {
                    var value = valueAccessor();
                    value.id = value.id || ko.bindingHandlers.uniqueId.prefix + (++ko.bindingHandlers.uniqueId.counter);

                    element.id = value.id;
                },
                counter: 0,
                prefix: "unique"
            };
// 這是為每個element生成不同ID
            ko.bindingHandlers['uniqueName'] = {
                'currentIndex': 0,
                'init': function (element, valueAccessor) {
                    if (valueAccessor()) {
                        element.name = "ko_unique_" + (++ko.bindingHandlers['uniqueName'].currentIndex);
                        // Workaround IE 6/7 issue 
                        // - https://github.com/SteveSanderson/knockout/issues/197 
                        // - http://www.matts411.com/post/setting_the_name_attribute_in_ie_dom/ 
                        if (ko.utils.isIe6 || ko.utils.isIe7)
                            element.mergeAttributes(document.createElement("<input name='" + element.name + "'/>"), false);
                    }
                }
            };
// 這是為每個element生成不同Name 
            ko.bindingHandlers['dateName'] = {
                init: function (element, valueAccessor) {
                    if (valueAccessor()) {
                        $('#' + element.id).kendoDatePicker({ format: "MM/dd/yyyy" });
                    }
                }
            };
//這是為包含dateName的元素添加了一個DatePicker
            ko.bindingHandlers.valmsg = {
                init: function (element) {
                    element.setAttribute("data-valmsg-for", "ko_unique_" + ko.bindingHandlers.uniqueName.currentIndex);
                }
            };
//這是利用element的name顯示驗證信息
            ko.applyBindings(viewModel);

        });
        var OtherSource = function(data) {
            var self = this;

            self.Test = ko.observable(data.Test);
            self.Date = ko.observable(data.Date);
            self.Scores = ko.observable(data.Scores);
        };

        @{
            var otherSources = Json.Encode(Model..........);
        }

        var jsonOtherSources = @Html.Raw(otherSources);

        var viewModel = {
            OtherSources: ko.observableArray(ko.utils.arrayMap(jsonOtherSources, function(otherSource) {
                return new OtherSource(otherSource);
            })),

            addOtherSource: function() {
                this.OtherSources.push({
                    Test: ko.observable(""),
                    Date: ko.observable(""),
                    Scores: ko.observable("")
                });
            },

            removeOtherSource: function(otherSource) {
                this.OtherSources.remove(otherSource);
            },
        };

 

上述代碼的data-bind,addOtherSource,removeOtherSource等在官網都有詳細的說明。

那我就只說一下在項目中出現的代碼。

uniqueId ,uniqueName是增加的一些屬性,用來做驗證。最終生成的Html如下:

QQ圖片20140325144526

這樣就生成了MVC中 ValidationMessageFor類似的驗證代碼,幫助我們在在頁面層進行驗證

 

當看到uniqueId ,uniqueName的綁定和生成方式之后,覺得這代碼N。

這也是我要這篇文章的最初原因。

 

最后再來一點與本題無關,但是保存時候的需要用到的代碼吧

if ($("form#editForm").valid()) {

                var data = $.deparam($("form#editForm").serialize());
               
                data["OtherSources"] = ko.mapping.toJSON(viewModel.OtherSources);
               
                $.post('@Url.Action("actionName", "ctlName", new {area = "***"})', data, function(result) {
                    HandleAjaxResult(result);
                });
            }

 

 


var otherSources = Request.Form["OtherSources"];
if (!string.IsNullOrEmpty(otherSources))
{
    var otherSourceDtos = JsonConvert.DeserializeObject<List<OtherSourceDto>>(otherSources);
    //save data to db…….

}


免責聲明!

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



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