2015 年 9 月

第 30 卷,第 9 期

本文章是由機器翻譯。

資料點 - 再探 JavaScript 資料繫結 -- 本次主角為 Aurelia

Julie Lerman

Julie Lerman我從來大部分的前端開發人員,但每隔一段時間有理由来播放的 ui。我在 2012 年 6 月專欄中之後 Knockout.js 上, 看到使用者群組簡報挖掘和寫過一篇有關資料繫結使用 Knockout 的網站中的 OData (msdn.microsoft.com/magazine/jj133816)。幾個月後,我撰寫了關於新增到使您更輕鬆地使用資料繫結 Knockout.js 混合 Breeze.js (msdn.microsoft.com/magazine/jj863129)。當我撰寫了關於現代化舊的 ASP.NET 2.0 Web Form 應用程式和 2014年中一次使用 Knockout 時,我有餵食由一些朋友說 Knockout 是"因此 2012"。 例如 Angular 較新版的架構也沒有資料繫結還有更多。但並不真正有興趣"得多,"所以 Knockout 已為我沒問題。

其實現在它的 2015 Knockout 時仍然有效和相關和 JavaScript 資料繫結實在太酷了,我想要花一點時間了一個新的架構和選擇 Aurelia (Aurelia.io) 因為我知道這麼多的 Web 開發人員期待它。Rob Eisenberg 者背後 Durandal,另一個 JavaScript 用戶端架構,雖然他的移 Google 角度小組工作停止生產 Aurelia 已啟動。最後會離開 Angular 和而不是使 Durandal,建立 Aurelia 從頭組成。有很多有關 Aurelia 有趣的事情。我有更多學習肯定,但是想要與您分享一些我了解,以及一些欺騙的手段 EcmaScript 6 (ES6) 在 2015 年 6 月變成標準 JavaScript 的最新版本的資料繫結技巧。

ASP.NET Web 應用程式開發介面會提供資料給我的網站

我使用 ASP.NET Web API 我建置了公開我要使用 Entity Framework 6 保存的資料。Web API 有幾個簡單的方法來透過 HTTP 呼叫。

中顯示的 Get 方法 [圖 1, 、 一些查詢和分頁參數會接受並將它們傳遞到擷取一份忍者物件和其相關的氏族物件使用 Entity Framework DbContext 的儲存機制方法。一旦 Get 方法會產生結果的手中,它會將轉換成一組 ViewListNinja 資料傳輸物件 (Dto) 在其他地方定義這些結果。這是一個重要步驟 JSON 序列化,因為這是有點過度與其他忍回到氏族的循環參考。DTOs 與避免浪費會在網路上的資料量而我得到調整為更符合用戶端上的結果。

圖 1] 從 Web API 的 Get 方法

public IEnumerable<ViewListNinja> Get(string query = "",
  int page = 0, int pageSize = 20)
  {
    var ninjas = _repo.GetQueryableNinjasWithClan(query, page, pageSize);
    return ninjas.Select(n => new ViewListNinja
                              {
                                ClanName = n.Clan.ClanName,
                                DateOfBirth = n.DateOfBirth,
                                Id = n.Id,
                                Name = n.Name,
                                ServedInOniwaban = n.ServedInOniwaban
                              });
    }

[圖 2 擷取兩個忍者物件的查詢為基礎的顯示來自該方法會產生 JSON 的檢視。

JSON 結果的忍清單的 Web API 要求
[圖 2 JSON 結果的忍清單的 Web API 要求

查詢 Web API 使用 Aurelia 架構

Aurelia 典範配對一個檢視模型 (JavaScript 類別) 與其中一個檢視 (HTML 檔案) 和執行資料繫結兩者之間。因此,我有 ninjas.js 檔案和 ninjas.html 檔案。忍檢視模型就會定義為忍,及忍者物件的陣列:

export class Ninja {
  searchEntry = '';
  ninjas = [];
  ninjaId = '';
  ninja = '';
  currentPage = 1;
  textShowAll = 'Show All';
  constructor(http) {
    this.http = http;
  }

Ninjas.js 中最重要的方法是 retrieveNinjas 會呼叫 Web API:

retrieveNinjas() {
  return this.http.createRequest(
    "/ninjas/?page=" + this.currentPage +
    "&pageSize=100&query=" + this.searchEntry)
    .asGet().send().then(response => {
      this.ninjas = response.content;
    });
  }

在網站的其他地方我已經設定好的基底 URL 該 Aurelia 應用程式會尋找並併入要求 URL:

x.withBaseUrl('http://localhost:46534/api');

值得注意的是 ninjas.js 檔案只要 JavaScript。如果您已使用 Knockout,您可能還記得您必須設定使用 Knockout 標記法,以便在物件繫結至該標記,Knockout 知道該如何處理它的檢視模型。這並非 Aurelia 的情況。

回應現在包括忍清單和我把它設為我取得返回觸發要求的 ninjas.html 頁面的檢視模型的忍陣列。識別模型的標記中沒有任何東西 — 可具有處理因為模型搭配 HTML。事實上,大部分是頁面的標準 HTML 和某些 JavaScript,有幾個 Aurelia 會尋找及處理的特殊命令。

資料繫結、 字串內插補點和格式

最有趣部分是 ninjas.html 的 div、 用來顯示忍清單:

<div class="row">
  <div  repeat.for="ninja of ninjas">
    <a href="#/ninjas/${ninja.Id}" class="btn btn-default btn-sm" >
      <span class="glyphicon glyphicon-pencil" />  </a>
    <a click.delegate="$parent.deleteView(ninja)" class="btn btn-default btn-sm">
      <span class="glyphicon glyphicon-trash" />  </a>
    ${ninja.Name}  ${ninja.ServedInOniwaban ? '[Oniwaban]':''}
    Birthdate:${ninja.DateOfBirth | dateFormat}
  </div>
</div>

在該程式碼的第一個 Aurelia 特定標記是 repeat.for"忍者的忍,"哪一種迴圈 ES6 典範。Aurelia comprehends 檢視模型,因為它知道 「 忍"是定義為陣列的屬性。變數"忍者 」 可以是任何名稱,例如"foo"。 它只代表忍陣列中的每個項目。現在就只需逐一查看忍陣列中的項目。跳到其中的屬性會顯示的標記例如是"${忍者。名稱} 」。 這是 ES6 功能 Aurelia 利用,也就所謂的字串內插補點。字串內插補點輕鬆地撰寫使用變數內嵌在它們而不是,比方說,藉由串連的字串。因此變數的名稱 ="Julie,"我就可以撰寫在 JavaScript 中:

`Hi, ${name}!`

會當做 「 嗨 Julie! 」 Aurelia 利用 ES6 字串內插補點和推斷單向資料繫結時遇到的語法。因此,最後一行程式碼開頭為 ${忍者。Name} 會輸出以及其他 HTML 文字的忍者屬性。如果您在 C# 或 Visual Basic 中撰寫程式碼,值得注意的是字串內插補點 C# 6.0 和 Visual Basic 14 的新功能。

若要了解更多的 JavaScript 語法過程中,例如其實有相同的語法為 C# ServedInOniwaban 布林值的條件式評估跟 — 條件嗎?true: false。

我已經套用至 DateOfBirth 屬性的日期格式是另一個 Aurelia 功能而且如果您已使用 XAML 可能很熟悉。Aurelia 會使用值轉換器。我喜歡使用目前的 JavaScript 程式庫來協助日期和時間格式,並利用該日期 format.js 類別中:

import moment from 'moment';
export class dateFormatValueConverter {
  toView(value) {
  return moment(value).format('M/D/YYYY');
  }
}

記住您需要"ValueConverter"中的類別名稱。

頂端的 HTML 頁面的 [正下方的初始 < 範本 > 項目中,我有該檔案的參考:

<template>
  <require from="./date-format"></require>

現在字串內插補點便能夠在我的標記中尋找 dateFormat [ValueConverter] 並將它套用到輸出中所示 [圖 3

顯示具有屬性的所有忍透過繫結的一種方式所 Aurelia 字串內插補點
[圖 3 顯示具有屬性的所有忍透過繫結的一種方式所 Aurelia 字串內插補點

我想指出 div,但它的事件繫結資料繫結中繫結的另一個執行個體。請注意第一個超連結標記中我會使用一般的語法,href 屬性中內嵌 URL。不過,在第二個,我不使用 href。相反地,我使用 click.delegate。委派不是新的命令,但 Aurelia 不會是更強大比標準的 onclick 事件處理常式以特殊方式處理它。進一步了解在 bit.ly/1Jvj38Z。我將繼續專注於相關的資料繫結這裡。

編輯圖示會導致 URL,其中包括忍者的識別碼。我已經指示要路由傳送到一個稱為 Edit.html 頁面的 Aurelia 路由機制。這是繫結至類別中名為 Edit.js 的檢視模型。

最重要的 Edit.js 方法會擷取和儲存選取的忍者。現在讓我們著手 retrieveNinja:

retrieveNinja(id) {
  return this.http.createRequest("/ninjas/" + id)
    .asGet().send().then(response => {
      this.ninja = response.content;
    });
  }

這會建置類似的要求來做為我 Web API 之前,不過這一次附加至要求的識別碼。

Ninjas.js 類別中我忍陣列屬性的 [我的檢視模型結合了結果。這裡設定結果的單一物件,目前的檢視模型的忍者屬性。

以下是因為附加到 URI 的識別碼會呼叫 Web API 方法:

public Ninja Get(int id)
  {
    return _repo.GetNinjaWithEquipmentAndClan(id);
  }

這個方法的結果會比針對忍者清單傳回更豐富。[圖 4 顯示 JSON 傳回其中一個要求。

JSON 結果的單一忍者 WebAPI 要求
[圖 4 JSON 結果的單一忍者 WebAPI 要求

一旦我已送入我的檢視模型的結果,我可以忍者的屬性繫結至 HTML 網頁中的項目。這次我使用.bind 命令。Aurelia 會推斷是否項目應該是單向或雙向繫結或其他方法。事實上,如您所見 ninjas.html 中,它會使用其基礎繫結工作流程時出現字串插補。那里一次性的單向繫結使用它。在這裡,我正在使用.bind 命令,而繫結至輸入項目,因為 Aurelia 會推斷我想雙向繫結。這是其預設選擇,我可以藉由覆寫。 單向或另一個命令來.bind 取代。

為了保持簡潔,我會擷取相關的標記而不是周圍的項目。

以下是我傳遞 modelview 類別從模型中的忍者屬性的名稱屬性繫結的 input 項目:

<input value.bind="ninja.Name" />

而這裡是另一個繫結至 DateOfBirth 欄位這次。我喜歡我可以輕鬆地重複使用的日期格式值轉換器即使在此內容中、 使用語法我先前已經學過:

<input  value.bind="ninja.DateOfBirth | dateFormat"  />

我也想要列出的相同頁面上,類似於如何我列出忍所以可以編輯和刪除的設備。示範中,我已經為該清單中顯示為字串,遠但尚未實作編輯和刪除功能,也不加入設備的方法:

<div repeat.for="equip of ninja.EquipmentOwned">
  ${equip.Name} ${equip.Type}
</div>

[圖 5 顯示的表單資料繫結。

[編輯] 頁面顯示設備清單
[圖 5 顯示設備清單的編輯頁面

Aurelia 也有一個稱為 「 自動調整的繫結,讓它能夠適應其可用功能的瀏覽器或甚至會在傳遞的物件為基礎的繫結功能的功能。它很酷,並設計為能夠隨著時間而進展與瀏覽器和程式庫一起運作。您可以閱讀更多關於在彈性的繫結 bit.ly/1GhDCDB

目前您只能編輯忍者名稱、 出生日期和 Oniwaban 指標。當使用者取消選取在 Oniwaban Served 並點擊 [儲存] 按鈕時,這個動作會呼叫我的檢視模型儲存方法之前將資料推送回我的 Web 應用程式開發介面所進行一些有趣的東西。目前,如同 [圖 4, ,忍者物件是深層的圖形。我不需要傳送的所有備份將儲存相關的屬性。因為我使用 EF 另一端,我想要確定我未編輯的屬性也會移回使它們不取得資料庫中的 null 值取代。因此我建立稱為 ninjaRoot 上即時 DTO。我已經過宣告 ninjaRoot 為我的檢視模型的屬性。但是 ninjaRoot 定義將由我 Save 方法在我建置的方式 (請參閱 [圖 6)。我已經很小心地使用相同的屬性名稱和我 WebAPI 預期讓它可以還原序列化這個 API 中的已知忍者類型的大小寫。

圖 6 儲存編輯模型檢視中的方法

save() {
        this.ninjaRoot = {
          Id: this.ninja.Id,
          ServedInOniwaban: this.ninja.ServedInOniwaban,
          ClanId: this.ninja.ClanId,
          Name: this.ninja.Name,
          DateOfBirth: this.ninja.DateOfBirth,
          DateCreated: this.ninja.DateCreated,
          DateModified: this.ninja.DateModified
        };
        this.http.createRequest("/ninjas/")
          .asPost()
          .withHeader('Content-Type', 'application/json; charset=utf-8')
          .withContent(this.ninjaRoot).send()
          .then(response => {
            this.myRouter.navigate('ninjas');
          }).catch(err => {
            console.log(err);
          });
    }

請注意在此呼叫中的"asPost"方法。這可確保要求移至我的 Web API 中的 Post 方法:

public void Post([FromBody] object ninja)
{
  var asNinja =
    JsonConvert.DeserializeObject<Ninja>
    (ninja.ToString());
  _repo.SaveUpdatedNinja(asNinja);
}

JSON 物件還原序列化為本機的忍者物件,然後傳遞給我知道要更新此物件在資料庫中的儲存機制方法。

當我在我的網站回到忍清單的變更會反映在輸出中。

以上只是資料繫結

請記住 Aurelia 是一種更豐富架構比只是資料繫結,但我本質 true、 把焦點放在資料中我第一個步驟來探索這項工具。您可以在 Aurelia Web 站台得多了,而且沒有並且繁榮壯大社群 gitter.im/Aurelia/Discuss

我想要提供的 nod 感謝 tutaurelia.net 網站、 部落格系列有關 ASP.NET Web API 和 Aurelia 結合。我在顯示的忍清單我第一次傳遞的 leaned 作者 Bart Van Hoey 的部分 6。可能是這個發行項時,會有加入數列的其他文章。

這篇文章的下載會同時包含 Web API 方案和 Aurelia 網站。您可以在 Visual Studio 中使用 Web API 的解決方案。我已經建置了它在 Visual Studio 2015 使用 Entity Framework 6 與 Microsoft.NET Framework 4.6。如果您想要執行的網站,您需要瀏覽 Aurelia.io 以了解如何安裝 Aurelia 和執行網站的網站。您也可以看到我將示範我 Pluralsight 課程"取得開始使用 Entity Framework 6"此應用程式在 bit.ly/PS-EF6Start


Julie Lerman 是 Microsoft MVP、.net 和顧問 Vermont 山區中。您可以找到她針對資料存取和使用者群組和世界各地的研討會其他.NET 主題呈現。她的部落格網址 thedatafarm.com 和的著作 《 Programming Entity Framework 」 (2010) 以及程式碼第一版 (2011) 和 DbContext edition (2012) 全部從 O'Reilly Media。依照她在 Twitter 上 twitter.com/julielerman 並查看她 Pluralsight 課程 juliel.me/PS 影片


感謝以下技術專家對本文的審閱: Rob Eisenberg (Durandal Inc.)
Rob Eisenberg 已有十多年的經驗將焦點放在使用者介面架構和設計。他是例如 Caliburn.Micro 和 Durandal,使用過上千名開發人員世界各地的多個 UI 架構的建立者。先前的角度 2.0 小組成員 Rob 目前會導致 Aurelia 專案、 下一代 JavaScript 用戶端架構適用於行動、 桌面和 Web 運用簡單的慣例來加強您的創意。如需詳細 http://aurelia.io/