5. Bölüm: altını gizleme. js ile dinamik kullanıcı arabirimi oluşturmaPart 5: Creating a Dynamic UI with Knockout.js

, Mike te sonby Mike Wasson

Tamamlanmış projeyi indirDownload Completed Project

Knockout.js ile Dinamik Kullanıcı Arabirimi OluşturmaCreating a Dynamic UI with Knockout.js

Bu bölümde, yönetici görünümüne işlevsellik eklemek için altını gizleme. js ' yi kullanacağız.In this section, we'll use Knockout.js to add functionality to the Admin view.

Altını gizleme. js , HTML denetimlerini verilere bağlamayı kolaylaştıran bir JavaScript kitaplığıdır.Knockout.js is a Javascript library that makes it easy to bind HTML controls to data. Altını gizleme. js Model-View-ViewModel (MVVM) modelini kullanır.Knockout.js uses the Model-View-ViewModel (MVVM) pattern.

  • Model , iş etki alanındaki verilerin sunucu tarafı gösterimidir (bizim örneğimizde, ürünlerimiz ve siparişlerde).The model is the server-side representation of the data in the business domain (in our case, products and orders).
  • Görünüm sunum katmanıdır (HTML).The view is the presentation layer (HTML).
  • View-model , model verilerini tutan bir JavaScript nesnesidir.The view-model is a Javascript object that holds the model data. View-model, Kullanıcı arabiriminin kod soyutlamasıdır.The view-model is a code abstraction of the UI. HTML temsili bilgisine sahip değildir.It has no knowledge of the HTML representation. Bunun yerine, görünümün "öğe listesi" gibi soyut özelliklerini temsil eder.Instead, it represents abstract features of the view, such as "a list of items".

Görünüm, görünüm modeline veri ile bağlanır.The view is data-bound to the view-model. Görünüm modeli güncelleştirmeleri otomatik olarak görünüme yansıtılır.Updates to the view-model are automatically reflected in the view. Görünüm modeli Ayrıca, düğme tıklamaları gibi görünümden olayları alır ve model üzerinde bir sipariş oluşturma gibi işlemleri gerçekleştirir.The view-model also gets events from the view, such as button clicks, and performs operations on the model, such as creating an order.

İlk olarak View-model tanımlayacağız.First we'll define the view-model. Bundan sonra, HTML işaretlemesini görünüm modeline bağlayacağız.After that, we will bind the HTML markup to the view-model.

Aşağıdaki Razor bölümünü admin. cshtml öğesine ekleyin:Add the following Razor section to Admin.cshtml:

@section Scripts {
  @Scripts.Render("~/bundles/jqueryval")
  <script type="text/javascript" src="@Url.Content("~/Scripts/knockout-2.1.0.js")"></script> 
  <script type="text/javascript">
  // View-model will go here
  </script>
}

Bu bölümü dosyada herhangi bir yere ekleyebilirsiniz.You can add this section anywhere in the file. Görünüm işlendiğinde, Bölüm HTML sayfasının alt kısmında, kapatma </Body> etiketinden hemen önce görünür.When the view is rendered, the section appears at the bottom of the HTML page, right before the closing </body> tag.

Bu sayfanın tüm betiği, yorum tarafından belirtilen komut dosyası etiketinin içine alınacaktır:All of the script for this page will go inside the script tag indicated by the comment:

<script type="text/javascript">
  // View-model will go here
  </script>

İlk olarak, bir View-model sınıfı tanımlayın:First, define a view-model class:

function ProductsViewModel() {
    var self = this;
    self.products = ko.observableArray();
}

ko. observableArray , bir observableolarak adlandırılan, altını gizleme içindeki özel bir nesne türüdür.ko.observableArray is a special kind of object in Knockout, called an observable. Altını gizleme. js belgelerinden: bir observable, abonelere değişiklikler hakkında bildirimde bulunan bir "JavaScript nesnesidir."From the Knockout.js documentation: An observable is a "JavaScript object that can notify subscribers about changes." Bir observable 'ın içeriği değiştiğinde görünüm, eşleşecek şekilde otomatik olarak güncelleştirilir.When the contents of an observable change, the view is automatically updated to match.

products diziyi doldurmak için Web API 'sine bir AJAX isteği yapın.To populate the products array, make an AJAX request to the web API. Görünüm paketinde API için temel URI 'yi depoladığımızda hatırlayın (öğreticinin 4. bölümüne bakın).Recall that we stored the base URI for the API in the view bag (see Part 4 of the tutorial).

function ProductsViewModel() {
    var self = this;
    self.products = ko.observableArray();

    // New code
    var baseUri = '@ViewBag.ApiUrl';
    $.getJSON(baseUri, self.products);
}

Ardından, Products oluşturmak, güncelleştirmek ve silmek için View-model ' e işlevler ekleyin.Next, add functions to the view-model to create, update, and delete products. Bu işlevler, Web API 'sine AJAX çağrıları gönderir ve sonuçları kullanarak görünüm modelini güncelleştirir.These functions submit AJAX calls to the web API and use the results to update the view-model.

function ProductsViewModel() {
    var self = this;
    self.products = ko.observableArray();

    var baseUri = '@ViewBag.ApiUrl';

    // New code
    self.create = function (formElement) {
        // If the form data is valid, post the serialized form data to the web API.
        $(formElement).validate();
        if ($(formElement).valid()) {
            $.post(baseUri, $(formElement).serialize(), null, "json")
                .done(function (o) { 
                    // Add the new product to the view-model.
                    self.products.push(o); 
                });
        }
    }

    self.update = function (product) {
        $.ajax({ type: "PUT", url: baseUri + '/' + product.Id, data: product });
    }

    self.remove = function (product) {
        // First remove from the server, then from the view-model.
        $.ajax({ type: "DELETE", url: baseUri + '/' + product.Id })
            .done(function () { self.products.remove(product); });
    }

    $.getJSON(baseUri, self.products);
}

Şimdi en önemli bölüm: DOM daha fazla yüklendiğinde, ko. applyBindings işlevini çağırın ve ProductsViewModelyeni bir örneğini geçirin:Now the most important part: When the DOM is fulled loaded, call the ko.applyBindings function and pass in a new instance of the ProductsViewModel:

$(document).ready(function () {
    ko.applyBindings(new ProductsViewModel());
})

Ko. applyBindings yöntemi, gizlemeyi etkinleştirir ve görünüm modelini görünüme bağlar.The ko.applyBindings method activates Knockout and wires up the view-model to the view.

Artık bir görünüm modelimiz olduğuna göre, bağlamaları oluşturarız.Now that we have a view-model, we can create the bindings. Altını gizleme. js ' de, bunu HTML öğelerine data-bind öznitelikleri ekleyerek yapabilirsiniz.In Knockout.js, you do this by adding data-bind attributes to HTML elements. Örneğin, bir HTML listesini diziye bağlamak için foreach bağlamayı kullanın:For example, to bind an HTML list to an array, use the foreach binding:

<ul id="update-products" data-bind="foreach: products">

foreach bağlama, dizi boyunca yinelenir ve dizideki her nesne için alt öğeler oluşturur.The foreach binding iterates through the array and creates child elements for each object in the array. Alt öğelerdeki bağlamalar, dizi nesnelerinde özelliklere başvurabilir.Bindings on the child elements can refer to properties on the array objects.

Aşağıdaki bağlamaları "Update-Products" listesine ekleyin:Add the following bindings to the "update-products" list:

<ul id="update-products" data-bind="foreach: products">
    <li>
        <div>
            <div class="item">Product ID</div> <span data-bind="text: $data.Id"></span>
        </div>
        <div>
            <div class="item">Name</div> 
            <input type="text" data-bind="value: $data.Name"/>
        </div> 
        <div>
            <div class="item">Price ($)</div> 
            <input type="text" data-bind="value: $data.Price"/>
        </div>
        <div>
            <div class="item">Actual Cost ($)</div> 
            <input type="text" data-bind="value: $data.ActualCost"/>
        </div>
        <div>
            <input type="button" value="Update" data-bind="click: $root.update"/>
            <input type="button" value="Delete Item" data-bind="click: $root.remove"/>
        </div>
    </li>
</ul>

<li> öğesi, foreach bağlamasının kapsamı içinde meydana gelir.The <li> element occurs within the scope of the foreach binding. Bunun anlamı, products dizisindeki her ürün için öğeyi bir kez oluşturacak anlamına gelir.That means Knockout will render the element once for each product in the products array. <li> öğesi içindeki tüm bağlamalar, bu ürün örneğine başvurur.All of the bindings within the <li> element refer to that product instance. Örneğin, $data.Name üründeki Name özelliğine başvurur.For example, $data.Name refers to the Name property on the product.

Metin girişlerinin değerlerini ayarlamak için value bağlamayı kullanın.To set the values of the text inputs, use the value binding. Düğmeler, click bağlamasını kullanarak model görünümündeki işlevlere bağlanır.The buttons are bound to functions on the model-view, using the click binding. Ürün örneği her işleve bir parametre olarak geçirilir.The product instance is passed as a parameter to each function. Daha fazla bilgi için, altını gizleme. js belgeleri çeşitli bağlamaların iyi açıklamalarını içerir.For more information, the Knockout.js documentation has good descriptions of the various bindings.

Ardından, ürün Ekle formundaki Gönder olayı için bir bağlama ekleyin:Next, add a binding for the submit event on the Add Product form:

<form id="addProduct" data-bind="submit: create">

Bu bağlama, yeni bir ürün oluşturmak için görünüm modelinde create işlevini çağırır.This binding calls the create function on the view-model to create a new product.

Yönetici görünümü için kodun tamamı aşağıda verilmiştir:Here is the complete code for the Admin view:

@model ProductStore.Models.Product

@{
    ViewBag.Title = "Admin";
}

@section Scripts {
  @Scripts.Render("~/bundles/jqueryval")
  <script type="text/javascript" src="@Url.Content("~/Scripts/knockout-2.0.0.js")"></script> 
  <script type="text/javascript">
      function ProductsViewModel() {
          var self = this;
          self.products = ko.observableArray();

          var baseUri = '@ViewBag.ApiUrl';

          self.create = function (formElement) {
              // If valid, post the serialized form data to the web api
              $(formElement).validate();
              if ($(formElement).valid()) {
                  $.post(baseUri, $(formElement).serialize(), null, "json")
                      .done(function (o) { self.products.push(o); });
              }
          }

          self.update = function (product) {
              $.ajax({ type: "PUT", url: baseUri + '/' + product.Id, data: product });
          }

          self.remove = function (product) {
              // First remove from the server, then from the UI
              $.ajax({ type: "DELETE", url: baseUri + '/' + product.Id })
                  .done(function () { self.products.remove(product); });
          }

          $.getJSON(baseUri, self.products);
      }

      $(document).ready(function () {
          ko.applyBindings(new ProductsViewModel());
      })
  </script>
}

<h2>Admin</h2>
<div class="content">
    <div class="float-left">
    <ul id="update-products" data-bind="foreach: products">
        <li>
            <div>
                <div class="item">Product ID</div> <span data-bind="text: $data.Id"></span>
            </div>
            <div>
                <div class="item">Name</div> 
                <input type="text" data-bind="value: $data.Name"/>
            </div> 
            <div>
                <div class="item">Price ($)</div> 
                <input type="text" data-bind="value: $data.Price"/>
            </div>
            <div>
                <div class="item">Actual Cost ($)</div> 
                <input type="text" data-bind="value: $data.ActualCost"/>
            </div>
            <div>
                <input type="button" value="Update" data-bind="click: $root.update"/>
                <input type="button" value="Delete Item" data-bind="click: $root.remove"/>
            </div>
        </li>
    </ul>
    </div>

    <div class="float-right">
    <h2>Add New Product</h2>
    <form id="addProduct" data-bind="submit: create">
        @Html.ValidationSummary(true)
        <fieldset>
            <legend>Contact</legend>
            @Html.EditorForModel()
            <p>
                <input type="submit" value="Save" />
            </p>
        </fieldset>
    </form>
    </div>
</div>

Uygulamayı çalıştırın, yönetici hesabıyla oturum açın ve "Yönetici" bağlantısına tıklayın.Run the application, log in with the Administrator account, and click the "Admin" link. Ürünlerin listesini görmeniz ve ürün oluşturabilir, güncelleştirebilir veya silebilirsiniz.You should see the list of products, and be able to create, update, or delete products.