استفاده از Knockout در MVC

در این مقاله نحوه به کارگیری ارزشیابی Knockout در MVC را شرح خواهیم داد

استفاده از  Knockout در MVC

نکته : این مثال برای افراد مبتدی مناسب نمی باشد و از توضیح موارد ابتدایی پرهیز شده است.

در این مقاله نحوه به کارگیری ارزشیابی   Knockout در MVC را شرح خواهیم داد.Knockout یک راه بسیار ساده برای اعمال تأیید اعتبار  است که می تواند در مقادیر مختلف استفاده می شود. انواع مختلفی از امکان سنجی موجود در Knockout ، از جمله برای ایمیل، اجباری پر کرددن فیلد، حداقل مقدار، حداکثر مقدارو غیره.

در پوشه Models خود یک اینترفیس به نام IProductRepository تعریف کردیم با چند تابع سپس در کلاس ProductRepository بدنه توابع را پیاده سازی کردیم و یک مدل هم به نام Product که شامل چهار فیلد   id وTitle برای ایمیل که برای این فیلد دو صفت اجباری بودن و فرمت صحیح ایمیل در نظز گرفته شده است سپس در پوشه کنترلر خود یک کنترلر  به نام Product میسازیم ویک متد به نام Product مینویسیم که برای آن یک ویو میسازیم کاری که میخواهیم انجام دهیم این است که برخی از اعتبارسنجی ها را بکارگیری کنیم و دکمه را تنها زمانی فعال کنیم که تما اعتبار سنجی ها انجام شده باشد برای اعتبار سنجی توسط Knockout به دو فایل زیر نیاز داریم:

1- Knockout.Validations.js

2-Knockout.Validations.Debug.js

حال از طریق Package Manager Console ، Nuget آنرا توسط دستور زیر بر روی پروژه نصب میکنیم:

PM> Install-Package Knockout.Validation

در حال حاضر ما فایل های لازم برای اعتبار سنجی Knockout را نصب کردیم حالا به  پیکربندی این validation ها نیاز داریم پس تنظیمات زیر را در تابع  ProductViewModel انجام می دهیم:

            ko.validation.rules.pattern.message = 'Invalid.';

            ko.validation.configure({
                registerExtenders: true,
                messagesOnModified: true,
                insertMessages: true,
                parseInputAttributes: true,
                messageTemplate: null
            });

این کد Validation ها را به طوری که شما می توانید آنها را به راحتی استفاده کنید پیکربندی می کند.

حالا اعتبارسنجی را روی یکی از فیلد ها به کار گیری میکنیم من چهار اعتبار سنجی را به کار گیری میکنم که انواع اعتبارسنجی را به شما نشان میدهد:

 var self = this;

            self.Id = ko.observable("");

            self.Title = ko.observable("").extend({ required: true, minLength: 2, maxLength: 40, email: true });

            self.Cost = ko.observable("");

            self.Class = ko.observable("");

همانطور که مشخص است این چهار اعتبار سنجی روی فیلد Title  انجام شده است برای به کار گیری اعتبار سنجی ها شما باید از تابع extend  استفاده کنیدValidation هایی که استفاده شده اند به شکل زیر هستیند:

1- Required : این Validation  زمانی که مقدار true  میگیرد به معنی این است که پر کردن این فیلد اجباری است یعنی کاربر نمیتواند این فیلد را خالی ترک کند.

2- minLength:2 : این Validation  بررسی میکند که کاربر حداقل دو(عددی که جلوی آن وارد شده) کاراکتر وارد کند.

3- maxLength: 40 این Validation  بررسی میکند که کاربر حداکثر چهل (عددی که جلوی آن وارد شده) کاراکتر وارد کند.

4-email : این Validation بررسی میکند که کاربر یک آدرس ایمیل معتبر وارد کند.

حال از یک textBox برای title  استفاده میکنم که با Validation های بالا محدود خواهد شد:http://localhost:6458/

<div>

            <label>ایمیل:-</label>

            <input id="txt2" data-bind="value: Title, valueUpdate: 'keyup'" title="Title" type="text" />

        </div>

 این TextBox هر زمان که رویداد keyup اتفاق بیفتد بروزرسانی خواهد شد یک دکمه به نام بررسی اضافه میکنیم:

 <button id="btn1" data-bind="enable:Title.isValid">بررسی</button>

این دکمه تا زمانی که مقدار صحیح برای فیلد title  وارد نشود غیر فعال است و زمانی که مقدار صحیح وارد شد فعال خواهد شد و میتوانید روی آن کلیک کنید که پیام خوش آمدگویی برای شما نشان داده میشود

کد کامل ویو Product به شکل زیر خواهد شد:

@{
    ViewBag.Title = "لیست";
}
<script src="@Url.Content("~/Scripts/jquery-ui-1.9.2.js")"></script>
<script src="~/Scripts/knockout-2.2.0.js"></script>
<script src="@Url.Content("~/Scripts/knockout-2.2.0.debug.js")" type="text/javascript"></script>
<script src="~/Scripts/knockout.validation.js"></script>
<script src="~/Scripts/knockout.validation.debug.js"></script>
<script src="~/Scripts/jquery.validate-vsdoc.js"></script>
<script src="~/Scripts/jquery.validate.js"></script>

@section scripts {
    <style type="text/css">
        body {
            margin: 20px;
            font-family: "Arial", "Helventica", sans-serif;
            direction: rtl
        }

        label {
            width: 80px;
            display: inline-block;
        }

        button {
            display: inline-block;
            outline: none;
            cursor: pointer;
            text-align: center;
            text-decoration: none;
            padding: .4em 1.1em .4em;
            color: #fef4e9;
            border: solid 1px #006fb9;
            background: #1276bb;
        }

        .test {
            background: #808080;
            cursor: none;
        }

        /*button:hover {
                text-decoration: none;
                background: #282828;
                border: solid 1px #000;
            }*/

        table {
            padding-top: 1em;
        }

        thead, tfoot {
            font-weight: 600;
        }

        th, td {
            padding: .1em .5em;
            text-align: left;
        }

            td li, td ul {
                margin: 0;
                padding: 0;
            }

            td li {
                display: inline;
            }

                td li::after {
                    content: ',';
                }

                td li:last-child::after {
                    content: '';
                }
    </style>


    <script type="text/javascript">

        function formatCurrency(value) {
            return "$" + value.toFixed(2);
        }

        function ProductViewModel() {
            ko.validation.rules.pattern.message = 'نا معتبر.';

            ko.validation.configure({
                registerExtenders: true,
                messagesOnModified: true,
                insertMessages: true,
                parseInputAttributes: true,
                messageTemplate: null
            });
            ko.validation.registerExtenders();
            //Make the self as 'this' reference
            var self = this;
            //Declare observable which will be bind with UI 
            self.Id = ko.observable("");
            self.Title = ko.observable("").extend({ required: true, minLength: 2, maxLength: 40, email: true });
            self.Cost = ko.observable("");
            self.Class = ko.observable("");

            var Product = {
                Id: self.Id,
                Title: self.Title,
                Cost: self.Cost,
                Class: self.Class
            };

            self.Product = ko.observable();
            self.Products = ko.observableArray();   // Contains the list of products

            // Initialize the view-model
            $.ajax({
                url: '@Url.Action("GetAllProducts", "Product")',
                cache: false,
                type: 'GET',
                contentType: 'application/json; charset=utf-8',
                data: {},
                success: function (data) {
                    self.Products(data); //Put the response in ObservableArray
                }
            });

            // Calculate Total of Cost After Initialization
            self.Total = ko.computed(function () {
                var sum = 0;
                var arr = self.Products();
                for (var i = 0; i < arr.length; i++) {
                    sum += arr[i].Cost;
                }
                return sum;
            });

            //Add New Item
            self.create = function () {
                debugger;
                //if (Product.Title() != "" && Product.Cost() != "" && Product.Class() != "")
                if (Product.Title() != "") {
                    $.ajax({
                        url: '@Url.Action("AddProduct", "Product")',
                        cache: false,
                        type: 'POST',
                        contentType: 'application/json; charset=utf-8',
                        data: ko.toJSON(Product),
                        success: function (data) {
                            //self.Products(data);

                            //
                            self.Products.push(data);
                            self.Title("");
                            self.Cost("");
                            self.Class("");
                            alert('added');
                            //if ($('#txt1').val() == self.Title("Hello")) {
                            //    alert("Welcome");
                            //}

                        }
                    }).fail(
                         function (xhr, textStatus, err) {
                             alert(err);
                         });

                }
                else {
                    alert('لطفا همه مقادیر را وارد کنید !!');
                }

            }
            // Delete product details
            self.delete = function (Product) {
                if (confirm('Are you sure to Delete "' + Product.Title + '" product ??')) {
                    var id = Product.Id;

                    $.ajax({
                        url: '@Url.Action("AddProduct", "Product")',
                        cache: false,
                        type: 'POST',
                        contentType: 'application/json; charset=utf-8',
                        data: ko.toJSON(id),
                        success: function (data) {
                            self.Products.remove(Product);
                            //   alert("Record Deleted Successfully");
                        }
                    }).fail(
                     function (xhr, textStatus, err) {
                         alert(err);
                     });
                    }
            }

            //if(Product.Title.length==0)
                $('#btn1').click(function () {
                    alert("خوش آمدید");
                    $('#btn1').attr('disabled', 'disabled');
                });

            //$(document).ready(function () {
            //    $('#btn1').attr('disabled', 'disabled');
            //    alert("hi");
            //    if (self.Title().length == 0) {
            //        $('#btn1').attr('disabled', 'disabled');

            //    }
            //    $('#txt2').on('change', function () {
            //        if (self.Title().length >= 1) {
            //        $('#btn1').removeAttr('disabled');
            //        alert("enabled");
            //        }
            //    });
            //    $('#btn1').click(function () {
            //        alert("Welcome");
            //        $('#btn1').attr('disabled', 'disabled');
            //    });
            //})



            //$(document).ready(function () {
            //    $('#btn1').attr('disabled', 'true');
            //    $('#txt2').blur(function () {                    
            //        if ($('#txt2').val() != "") {
            //            if ($('#txt2').val() == self.Title()) {
            //                //$('#btn1').removeClass('hover');
            //                //$('#btn1').css({ 'display': 'none' });
            //                $('#btn1').removeAttr('disabled');
            //                alert("Welcome");
            //            }
            //        }
            //        else {
            //            $('#btn1').attr('disabled', 'true');                                                 
            //                alert("please enter");
            //        }
            //    });
            //});
            //$('#try').click(function () {
            //    $('#btn1').removeAttr('disabled').removeClass("test");
            //});

            // Edit product details

                self.edit = function (Product) {
                    self.Product(Product);

                }

            // Update product details
                self.change = function () {
                    var Product = self.Product();

                    $.ajax({
                        url: '@Url.Action("EditProduct", "Product")',
                        cache: false,
                        type: 'PUT',
                        contentType: 'application/json; charset=utf-8',
                        data: ko.toJSON(Product),
                        success: function (data) {
                            self.Products.removeAll();
                            self.Products(data); //Put the response in ObservableArray
                            self.Product(null);
                            alert("اطلاعات با موفقیت ویرایش شد");

                        }
                    })
                .fail(
                function (xhr, textStatus, err) {
                    alert(err);
                });
                }


            // Reset product details
                self.reset = function () {
                    self.Title("");
                    self.Cost("");
                    self.Class("");
                }

            // Cancel product details

                self.cancel = function () {
                    self.Product(null);

                }
            }
            var viewModel = new ProductViewModel();
            ko.applyBindings(viewModel);


    </script>
    <script type="text/javascript">
        
    </script>
}


<div id="body">

    @*    <h2>CRUD Operations Using Knockout</h2>

    <h3>Items List</h3>

    <table id="products1" data-bind="visible: Products().length > 0">
        <thead>
            <tr>
                <th>ID</th>
                <th>Title</th>
                <th>Class</th>
                <th>Cost</th>
                <th>Actions</th>
            </tr>
        </thead>
        <tbody data-bind="foreach: Products">
            <tr>
                <td data-bind="text: Id"></td>
                <td data-bind="text: Title"></td>
                <td data-bind="text: Class"></td>
                <td data-bind="text: formatCurrency(Cost)"></td>

                <td>
                    <button data-bind="click: $root.edit">Edit</button>
                    <button data-bind="click: $root.delete">Delete</button>

                </td>

            </tr>
        </tbody>
        <tfoot>
            <tr>
                <td></td>
                <td></td>
                <td>Total :</td>
                <td data-bind="text: formatCurrency($root.Total())"></td>
                <td></td>
            </tr>
        </tfoot>
    </table>
    <br />
    <div style="border-top: solid 2px  #282828; width: 430px; height: 10px">&nbsp;</div>*@

    <div data-bind="if: Product">
        @*        <div>
            <h2>Item Updation</h2>
        </div>
        <div>
            <label for="productId" data-bind="visible: false">ID</label>
            <label data-bind="text: Product().Id, visible: false"></label>

        </div>
        <div>
            <label for="name">Title</label>
            <input data-bind="value: Product().Title" type="text" title="Title" />
        </div>

        <div>
            <label for="category">Class</label>
            <input data-bind="value: Product().Class" type="text" title="Class" />
        </div>

        <div>
            <label for="price">Cost</label>
            <input data-bind="value: Product().Cost" type="text" title="Cost" />

        </div>
        <br />
        <div>
            <button data-bind="click: $root.change">Change</button>
            <button data-bind="click: $root.cancel">Cancel</button>

        </div>*@
    </div>

    <div data-bind="ifnot: Product()">
        <div>
            <h2>افزودن</h2>
        </div>
        <div>
            <label for="name">ایمیل</label>
            <input data-bind="value: $root.Title" type="text" id="txt1" title="Title" />
        </div>

        <div>
            <label for="category">کلاس</label>
            <input data-bind="value: $root.Class" type="text" title="Class" />
        </div>

        <div>
            <label for="price">هزینه</label>
            <input data-bind="value: $root.Cost" type="text" title="Cost" />
        </div>
        <div>
            <label>مقدار را اینجا وارد کنید:-</label>
            <input id="txt2" data-bind="value: Title, valueUpdate: 'keyup'" type="text" />
        </div>
        <br />
        <div>
            <button data-bind="click: $root.create">تایید</button>
            <button data-bind="click: $root.reset">راه اندازی مجدد</button>
            <button id="btn1" data-bind="enable:Title.isValid">بررسی</button>
            <button id="try">تلاش مجدد</button>

        </div>
    </div>

</div>

حالا میتوانید برنامه رو اجرا کنید:

 

فایل های ضمیمه