Část 5: Vytvoření dynamického uživatelského rozhraní pomocí Knockout.js

Rick Anderson

Stažení dokončeného projektu

Vytvoření dynamického uživatelského rozhraní s knihovnou Knockout.js

V této části použijeme Knockout.js k přidání funkcí do zobrazení Správa.

Knockout.js je javascriptová knihovna, která usnadňuje svázání ovládacích prvků HTML s daty. Knockout.js používá model Model-View-ViewModel (MVVM).

  • Model představuje na straně serveru reprezentaci dat v obchodní doméně (v našem případě produkty a objednávky).
  • Zobrazení je prezentační vrstva (HTML).
  • View-model je javascriptový objekt, který obsahuje data modelu. Model zobrazení je abstrakcí kódu uživatelského rozhraní. Nemá žádné znalosti o reprezentaci HTML. Místo toho představuje abstraktní funkce zobrazení, například "seznam položek".

Zobrazení je svázané s modelem zobrazení. Aktualizace k modelu zobrazení se v zobrazení automaticky projeví. Model zobrazení také získává události ze zobrazení, například kliknutí na tlačítko, a provádí operace s modelem, jako je například vytvoření objednávky.

Diagram interakce mezi daty H T M L, modelem zobrazení, j son a kontrolerem Web A P I

Diagram znázorňující interakci mezi daty H T M L, view-model, j son a kontrolerem Web A P I Datový box H T M L je označený jako zobrazení. Dvojitá šipka označená datovou vazbou propojuje datové pole H T M L s polem modelu zobrazení. Dvojitá šipka označená požadavky H T T P a model j son ze serveru propojuje view-model s kontrolerem Web A P I.

Nejprve definujeme view-model. Poté svážeme kód HTML s modelem zobrazení.

Do souboru Správa.cshtml přidejte následující oddíl Razor:

@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>
}

Tento oddíl můžete přidat kamkoli do souboru. Při vykreslení zobrazení se oddíl zobrazí v dolní části stránky HTML přímo před zavírací <značkou /body> .

Všechny skripty pro tuto stránku se přesunou do značky script označené komentářem:

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

Nejprve definujte třídu view-model:

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

ko.observableArray je speciální druh objektu v Knockout, který se nazývá pozorovatelný. Z Knockout.js dokumentace: Pozorovatelný je javascriptový objekt, který může odběratele upozornit na změny. Když se obsah pozorovatelné změny změní, zobrazení se automaticky aktualizuje tak, aby odpovídalo.

Pokud chcete naplnit products pole, vytvořte požadavek AJAX na webové rozhraní API. Vzpomeňte si, že jsme základní identifikátor URI rozhraní API uložili do kontejneru zobrazení (viz část 4 kurzu).

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

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

Dále do modelu zobrazení přidejte funkce pro vytváření, aktualizaci a odstraňování produktů. Tyto funkce odesílají volání AJAX do webového rozhraní API a pomocí výsledků aktualizují model zobrazení.

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);
}

Nejdůležitější část: Když je model DOM načtený, zavolejte funkci ko.applyBindings a předejte novou instanci objektu ProductsViewModel:

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

Metoda ko.applyBindings aktivuje Knockout a provádí view-model se zobrazením.

Teď, když máme model zobrazení, můžeme vytvořit vazby. V Knockout.js to uděláte tak, že do elementů HTML přidáte data-bind atributy. Pokud například chcete vytvořit vazbu mezi seznamem HTML a polem, použijte tuto foreach vazbu:

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

Vazba foreach iteruje polem a vytváří podřízené prvky pro každý objekt v poli. Vazby na podřízené prvky mohou odkazovat na vlastnosti objektů pole.

Do seznamu update-products přidejte následující vazby:

<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>

Prvek <li> se vyskytuje v rámci rozsahu vazby foreach . To znamená, že Knockout vykreslí prvek jednou pro každý produkt v poli products . Všechny vazby v rámci elementu <li> odkazují na instanci tohoto produktu. Například $data.Name odkazuje na Name vlastnost produktu.

K nastavení hodnot textových vstupů použijte value vazbu. Tlačítka jsou svázaná s funkcemi v zobrazení modelu pomocí vazby click . Instance produktu se předává jako parametr každé funkci. Další informace najdete v dokumentaci kKnockout.js s dobrým popisem různých vazeb.

Dále přidejte vazbu pro událost odeslání ve formuláři Přidat produkt:

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

Tato vazba volá create funkci view-model k vytvoření nového produktu.

Tady je úplný kód pro zobrazení Správa:

@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>

Spusťte aplikaci, přihlaste se pomocí účtu správce a klikněte na odkaz Správa. Měli byste vidět seznam produktů a měli byste mít možnost produkty vytvářet, aktualizovat nebo odstraňovat.