Ractive.js - Web Uygulamaları Kolaylaştırıldı

Yayınlanan: 2022-03-11

Günümüzün hızla çoğalan JavaScript çerçeveleri ve kitaplıkları ortamında, geliştirmenizi temel almak istediğinizi seçmek oldukça zor olabilir. Sonuçta, belirli bir çerçeveyi kullanma yoluna girdikten sonra, kodunuzu farklı bir çerçeveye geçirmek, gerçekleştirmek için asla zamanınız veya bütçeniz olmayabilir, önemsiz olmayan bir görevdir.

Peki neden Ractive.js?

Eylemsiz HTML oluşturan diğer araçların aksine, Ractive, şablonları varsayılan olarak etkileşimli uygulamalar için planlara dönüştürür. Ve Ractive'in katkısının devrimci olmaktan çok evrimsel olduğu kesinlikle iddia edilebilirken, değeri yine de önemlidir.

Ractive'i bu kadar kullanışlı yapan şey, güçlü yetenekler sağlaması, ancak bunu geliştiricinin kullanması için canlandırıcı bir şekilde basit bir şekilde yapmasıdır. Üstelik oldukça zarif, hızlı, göze batmayan ve küçük.

Bu makalede, basit bir Ractive arama uygulaması oluşturma sürecini inceleyeceğiz, Ractive'in bazı temel özelliklerini ve web uygulamalarını ve geliştirmeyi basitleştirmeye nasıl yardımcı olduğunu göstereceğiz.

Ractive.js ve web uygulamaları

Ractive.js nedir?

Ractive, başlangıçta veri bağlama sorununu daha zarif bir şekilde çözmek için oluşturuldu. Bu amaçla, şablonları alır ve bunları DOM'nin hafif bir sanal temsiline dönüştürür, böylece veriler değiştiğinde gerçek DOM akıllı ve verimli bir şekilde güncellenir.

Ancak kısa süre sonra, Ractive tarafından kullanılan yaklaşım ve altyapının başka şeyleri daha verimli bir şekilde yapmak için de kullanılabileceği ortaya çıktı. Örneğin, olay işleyicileri yeniden kullanmak ve artık ihtiyaç duyulmadığında bunları otomatik olarak kaldırmak gibi şeyleri otomatik olarak halledebilir. Etkinlik delegasyonu gereksiz hale gelir. Veri bağlamada olduğu gibi, bu yaklaşım, bir uygulama büyüdükçe kodun hantal hale gelmesini önler.

İki yönlü bağlama, animasyonlar ve SVG desteği gibi temel özellikler kullanıma hazır olarak sağlanır ve eklentiler aracılığıyla özel işlevler kolayca eklenebilir.

Bazı araçlar ve çerçeveler sizi yeni bir kelime öğrenmeye ve uygulamanızı belirli bir şekilde yapılandırmaya zorlarken, Ractive tam tersi değil sizin için çalışır. Ayrıca diğer kütüphanelerle iyi bir şekilde bütünleşir.

Örnek Uygulamamız

Örnek uygulamamız, becerilere dayalı olarak geliştiricilerin Toptal veritabanında arama yapmak için kullanılacaktır. Uygulamamızın iki görünümü olacaktır:

  • Arama: satır içi arama kutusuyla beceri listesi
  • Sonuçlar: geliştiricilerin listesini içeren beceri görünümü

Her geliştirici için adını, fotoğrafını, kısa açıklamasını ve becerilerin bir listesini görüntüleyeceğiz (her beceri ilgili beceri görünümüne bağlanacaktır).

(Not: Uygulamanın çevrimiçi çalışan bir örneğine ve kaynak kod deposuna bağlantılar bu makalenin sonunda verilmiştir.)

Öncelikli odağımızı Ractive çerçevesine sürdürmek için normalde üretimde yapılmaması gereken bir dizi basitleştirmeyi kullanacağız:

  • Varsayılan tema. Temayı uygulama stilinize uyacak şekilde özelleştirmek yerine, stil için varsayılan temayla Bootstrap kullanacağız.
  • bağımlılıklar Bağımlılıklarımızı, global değişkenleri tanımlayan ayrı komut dosyaları olarak ekleyeceğiz (geliştirme için uygun yükleyiciyle ES6 modüllerini veya CommonJS'yi veya AMD'yi ve üretim için oluşturma adımını kullanmak yerine).
  • Statik veriler. Toptal sitesindeki genel sayfaları kazıyarak hazırladığım statik verileri kullanacağız.
  • İstemci tarafı yönlendirme yok. Bu, görünümler arasında geçiş yaptığımızda URL'nin aynı kalacağı anlamına gelir. Bunu SPA'lar için kesinlikle yapmamalısınız, ancak bazı küçük etkileşimli bileşenler için uygun olabilir. Ractive'in yerleşik bir yönlendirici uygulaması yoktur, ancak bu örnekte gösterildiği gibi 3. taraf yönlendiricilerle kullanılabilir.
  • HTML'de komut dosyası etiketlerinin içinde tanımlanan şablonlar. Bu, özellikle küçük uygulamalar için mutlaka kötü bir fikir değildir ve bazı avantajları vardır (basittir ve bu istemci tarafı şablonlarını, örneğin uluslararasılaştırma için sunucu tarafı şablonlarınızla birlikte işleyebilirsiniz). Ancak daha büyük uygulamalar için ön derlemeden yararlanabilirsiniz (diğer bir deyişle, şablonları dahili JS temsiline önceden ayrıştırma.

Web Uygulamalarına Başlayalım

Tamam, bunu söyledikten sonra uygulamayı oluşturmaya başlayalım. Daha küçük özellikleri birer birer ekleyerek ve karşılaştığımız kavramları keşfederek, yinelemeli bir şekilde yapacağız.

İçinde iki dosya bulunan bir klasör oluşturarak başlayalım: index.html ve script.js . Uygulamamız son derece basit olacak ve geliştirme sunucusunu başlatma ihtiyacından kaçınmak için file:// protokolünden çalışacaktır (ancak isterseniz yapabilirsiniz).

Arama Sayfası

Kullanıcının Toptal veritabanında eşleşen geliştiricileri bulabileceği bir beceri seçebileceği arama sayfasını uygulayarak başlayacağız.

HTML İskeleti

Bu önemsiz HTML sayfasıyla başlayalım:

 <html> <head> <title>Toptal Search</title> <!-- LOAD BOOTSTRAP FROM THE CDN --> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css"> </head> <body> <!-- SOME BASIC STATIC CONTENT --> <div class="container"> <h1>Toptal Search</h1> </div> <!-- LOAD THE JAVASCRIPT LIBRARIES WE NEED --> <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.9.3/lodash.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/ractive/0.7.3/ractive.min.js"></script> <!-- LOAD THE DATA --> <script src="https://rawgit.com/emirotin/toptal-blog-ractive/master/data.js"></script> <!-- LOAD OUR SCRIPT --> <script src="script.js"></script> </body> </html>

Gördüğünüz gibi, önemsiz bir HTML5 belgesi. Bootstrap'i CDN, Lodash (harika bir veri işleme kitaplığı) ve Ractive.js'den yükler.

Ractive, tüm sayfayı SPA'ya ayırmayı gerektirmez, bu yüzden biraz statik içeriğe sahip olabiliriz. Bizim durumumuzda bu, bir kapsayıcı öğesinden ve sayfa başlığından oluşur.

Son olarak demo için hazırladığım datayı ve programımızın yer alacağı scripti yüklüyoruz.

Tamam, şimdi HTML iskeletimiz yerine oturduğuna göre, bazı gerçek işlevler eklemeye başlayalım.

Beceri Listesi

Ractive hakkında özellikle sevdiğim şeylerden biri, size ulaşmak istediğiniz nihai temsil (HTML) hakkında düşünmeyi öğretmesi ve ardından bunun gerçekleşmesi için gerekli kod parçalarını yazmaya odaklanmanızı sağlamasıdır.

İlk olarak, ilk görüşümüz olarak bir beceri listesi oluşturalım. Bunu yapmak basitçe şunları içerir:

  • Beceri listesinin görüntüleneceği bir HTML öğesi ekleme.
  • HTML'mize küçük bir şablon kodu parçacığı ekleme.
  • Eklediğimiz HTML öğesinde işlemek için verileri şablona sağlayan kısa ve basit bir JavaScript yazmak.

HTML'nin modları aşağıdakilerden oluşur:

 <div class="container"> <h1>Toptal Search</h1> <div></div> <!-- THIS IS THE NEW HTML ELEMENT --> </div> <!-- THIS IS THE SMALL SNIPPET OF TEMPLATE CODE --> <script type="text/html"> <div class="row"> {{#each skills}} <span class="col-xs-3"> <a href="#" class="label label-primary">{{this}}</a> </span> {{/each}} </div> </script>

Görüntülenecek verileri alacak HTML öğesini belirtmek için Ractive ile özel bir kural yoktur, ancak bunu yapmanın en basit yolu öğeye bir kimlik eklemektir. Bu amaçla genellikle "kök" kimliğini kullanırım. Ractive başlatıldığında nasıl kullanıldığını yakında göreceğiz. Merak edenler için kök öğeyi belirtmenin başka yolları da var.

type="text/html" içeren biraz garip komut dosyası öğesi, tarayıcılar bilinmeyen türdeki komut dosyalarını yok saydığından, tarayıcı tarafından ayrıştırılmadan veya oluşturulmadan yüklenen bir HTML yığınını elde etmek için akıllıca bir numaradır. Komut dosyasının içeriği Bıyık/Gidon benzeri bir şablondur (ancak Ractive'in bazı uzantıları vardır).

Skill dizisine erişimimiz olduğunu varsayarak ilk önce şablon kodunu yazıyoruz. Yinelemeyi tanımlamak için {{#each}} bıyık yönergesini kullanıyoruz. Yönergenin içinde, mevcut öğeye this şekilde erişilebilir. Yine, skill değişkeninin bir dizi diziye sahip olduğunu varsayıyoruz, bu yüzden onu basitçe enterpolasyon bıyığı {{this}} ile oluşturuyoruz.

Tamam, bu HTML. Peki ya JavaScript? Şablona veri sağlayan "sihir" işte burada gerçekleşir:

 (function () { var skills = DB.skills, developers = DB.developers; var app = new Ractive({ el: '#root', template: '#tpl-app', data: { skills: _.keys(DB.skills) } }); }());

Etkileyici, değil mi? Sadece bu 10 satırlık kodda şunları yapabiliyoruz:

  1. “DB” den verileri “alın”.
  2. Yeni bir Ractive uygulaması oluşturun.
  3. İle öğenin içini oluşturmasını söyleyin .
  4. İle bir komut dosyası öğesi kullanmasını söyleyin şablonu almak için (bunu yapmanın başka yolları da vardır).
  5. İlk verileri (çalışma zamanında nasıl değiştirileceğini göreceğiz) veya Angular terminolojiye alışkınsanız “kapsam”ı iletin.
  6. “DB” de nesne anahtarları olarak kullandığımız beceri adlarını almak için lodash keys yöntemini kullanın.

Yani temelde bu betik ile çerçeveye ne yapacağını söylüyoruz, ama nasıl yapacağını söylemiyoruz. Şablon, kişisel olarak oldukça şaşırtıcı ve doğal bulduğum nasıl olduğunu açıklıyor.

Umarım fikri anlamaya başlarsınız, şimdi elimizdekinin üzerine daha faydalı bir şey uygulayalım.

Beceri Arama

Arama sayfasının elbette bir arama alanına ihtiyacı vardır. Ayrıca, kullanıcı arama kutusuna yazarken, beceriler listesinin yalnızca girilen alt diziyi içerenleri içerdiği (filtreleme büyük/küçük harf duyarlı değildir) içeren etkileşimli bir yetenek sağlamasını istiyoruz.

Ractive'de olduğu gibi, şablonu tanımlayarak başlıyoruz (hangi yeni bağlam değişkenlerine ihtiyaç duyulacağını ve veri yönetimi açısından nelerin değişeceğini düşünürken):

 <div class="container"> <h1>Toptal Search</h1> <div></div> </div> <!-- THIS IS THE SMALL SNIPPET OF TEMPLATE CODE --> <script type="text/html"> <!-- HERE'S OUR SEARCH BOX --> <div class="row"> <form class="form-horizontal col-xs-6 col-xs-offset-6"> <input type="search" class="form-control" value="{{ skillFilter }}" placeholder="Type part of the skill name here"> </form> </div> <hr> <!-- NOW INSTEAD OF DISPLAYING ALL SKILLS, WE INVOKE A TO-BE-CREATED JAVASCRIPT skills() FUNCTION THAT WILL FILTER THE SKILL LIST DOWN TO THOSE THAT MATCH THE TEXT ENTERED BY THE USER --> <div class="row"> {{#each skills()}} <span class="col-xs-3"> <a href="#" class="label label-primary">{{this}}</a> </span> {{/each}} </div> </script>

Çok fazla değişiklik yok, ancak yine de öğrenilecek adil bir miktar.

İlk olarak, arama kutumuzu içeren yeni bir <div> ekledik. Bu girdiyi bir değişkene bağlamak istediğimiz oldukça açık (eski jQuery çorba günleri hakkında nostaljik değilseniz). Ractive, iki yönlü bağlamayı destekler; bu, JS kodunuzun DOM'dan manuel olarak okumaya gerek kalmadan bir değeri alabileceği anlamına gelir. Bizim durumumuzda bu, mustache value="{{ skillFilter }}" enterpolasyonu kullanılarak gerçekleştirilir. Ractive, bu değişkeni girdinin value niteliğine bağlamak istediğimizi anlıyor. Bu yüzden bizim için girdiyi izler ve değişkeni otomatik olarak günceller. Sadece 1 satır HTML ile oldukça temiz.

İkinci olarak, yukarıdaki kod parçacığındaki yorumda açıklandığı gibi, şimdi tüm becerileri görüntülemek yerine, beceri listesini filtreleyecek ve yalnızca kullanıcı tarafından girilen metinle eşleşenleri döndürecek bir skills() JS işlevi oluşturacağız:

 // store skill list in a variable outside of Ractive scope var skillNames = _.keys(DB.skills); var app = new Ractive({ el: '#root', template: '#tpl-app', data: { // initializing the context variable is not strictly // required, but it is generally considered good practice skillFilter: null, // Define the skills() function right in our data object. // Function is available to our template where we call it. skills: function() { // Get the skillFilter variable from the Ractive instance // (available as 'this'). // NOTE WELL: Our use of a getter here tells Ractive that // our function has a *dependency* on the skillFilter // value, so this is significant. var skillFilter = this.get('skillFilter'); if (!skillFilter) { return skillNames; } skillFilter = new RegExp(_.escapeRegExp(skillFilter), 'i') return _.filter(skillNames, function(skill) { return skill.match(skillFilter); }); } } });

Bu temiz ve uygulanması basit olsa da, performansı nasıl etkilediğini merak ediyor olabilirsiniz. Yani, her seferinde bir fonksiyon mu çağıracağız? Peki, her seferinde ne? Ractive, bağımlılıkları (değişkenleri) değiştiğinde şablonun yalnızca parçalarını yeniden oluşturacak (ve onlardan herhangi bir işlevi çağıracak) kadar akıllıdır (Ractive, ayarlayıcıların kullanımı sayesinde bunun ne zaman olduğunu bilir).

Bu arada, bunu bir adım daha ileri götürmekle ilgilenenler için, bunu hesaplanmış bir özellik kullanarak yapmanın daha zarif bir yolu da var, ancak isterseniz bunu kendi başınıza oynamanız için size bırakacağım.

Sonuçlar Sayfası

Artık oldukça kullanışlı, aranabilir bir beceri listemiz olduğuna göre, eşleşen geliştirici listesinin görüntüleneceği sonuç görünümüne geçelim.

Beceri Görünümü'ne ve Beceri Görünümünden geçiş

Bunun uygulanabileceği pek çok yol olduğu açıktır. Bir becerinin seçilip seçilmemesine göre iki farklı görüş olması yaklaşımını seçtim. Eğer öyleyse, eşleşen geliştiricilerin listesini gösteririz; değilse, beceri listesini ve arama kutusunu gösteririz.

Bu nedenle, yeni başlayanlar için, kullanıcı bir beceri adını seçtiğinde (yani tıkladığında), beceri listesinin gizlenmesi ve bunun yerine sayfa başlığı olarak beceri adının gösterilmesi gerekir. Tersine, seçilen beceri görünümünde, bu görünümü kapatmanın ve beceriler listesine geri dönmenin bir yolu olması gerekir.

İşte bu yolda ilk adımımız:

 <script type="text/html"> <!-- PARTIAL IS A NEW CONCEPT HERE --> {{#partial skillsList}} <div class="row"> <form class="form-horizontal col-xs-6 col-xs-offset-6"> <input type="search" class="form-control" value="{{ skillFilter }}" placeholder="Type part of the skill name here"> </form> </div> <hr> <div class="row"> {{#each skills()}} <span class="col-xs-3"> <!-- MAKE OUR SKILLS CLICKABLE, USING PROXY EVENTS --> <a href="#" class="label label-primary" on-click="select-skill:{{this}}">{{this}}</a> </span> {{/each}} </div> {{/partial}} {{#partial skillView}} <h2> <!-- DISPLAY SELECTED SKILL AS HEADING ON THE PAGE --> {{ currentSkill }} <!-- CLOSE BUTTON TAKES USER BACK TO SKILLS LIST --> <button type="button" class="close pull-right" on-click="deselect-skill">&times; CLOSE</button> </h2> {{/partial}} <!-- PARTIALS ARE NOT IN THE VIEW UNTIL WE EXPLICITLY INCLUDE THEM, SO INCLUDE THE PARTIAL RELEVANT TO THE CURRENT VIEW. --> {{#if currentSkill}} {{> skillView}} {{else}} {{> skillsList}} {{/if}} </script>

Tamam, burada çok şey oluyor.

İlk olarak, bunu iki farklı görüş olarak uygulamak için, şu ana kadar sahip olduğumuz her şeyi (yani, liste görünümü) kısmi denen bir şeye taşıdım. Kısmi, esasen farklı bir yere (yakında) dahil edeceğimiz bir şablon kodu yığınıdır.

Ardından, becerilerimizi tıklanabilir hale getirmek istiyoruz ve tıklandığında ilgili beceri görünümüne gitmek istiyoruz. Bunun için vekil olaylar adı verilen bir şey kullanırız, bu sayede fiziksel bir olaya tepki veririz (tıklandığında, isim Ractive tarafından anlaşılabilir olandır) ve onu mantıksal olaya (seçme-beceri, isim ne dersek odur) vekil ederiz. ) argümanı iletmek (muhtemelen hatırladığınız gibi, buradaki beceri adı anlamına gelir).

(Bilginize, aynı şeyi başarmak için alternatif bir yöntem çağrıları sözdizimi vardır.)

Ardından, (tekrar) seçilen becerinin adını taşıyan (varsa) currentSkill adında bir değişkenimiz olacağını veya hiçbir beceri seçilmemişse boş olacağını varsayıyoruz. Bu nedenle, mevcut beceri adını gösteren ve ayrıca beceri seçimini kaldırması gereken bir “KAPAT” bağlantısına sahip başka bir kısmi tanımlıyoruz.

JavaScript için ana ekleme, select-skill ve deselect-skill olaylarına abone olmak ve currentSkill (ve skillFilter ) buna göre güncellemek için kullanılan koddur:

 var app = new Ractive({ el: '#root', template: '#tpl-app', data: { skillFilter: null, currentSkill: null, // INITIALIZE currentSkill TO null // skills function remains unchanged skills: function() { var skillFilter = this.get('skillFilter'); if (!skillFilter) { return skillNames; } skillFilter = new RegExp(_.escapeRegExp(skillFilter), 'i') return _.filter(skillNames, function(skill) { return skill.match(skillFilter); }); } } }); // SUBSCRIBE TO LOGICAL EVENT select-skill app.on('select-skill', function(event, skill) { this.set({ // SET currentSkill TO THE SKILL SELECTED BY THE USER currentSkill: skill, // RESET THE SEARCH FILTER skillFilter: null }); }); // SUBSCRIBE TO LOGICAL EVENT deselect-skill app.on('deselect-skill', function(event) { this.set('currentSkill', null); // CLEAR currentSkill });

Her Beceri için Geliştiricileri Listeleme

Beceri için yeni görünümü hazırladıktan sonra, artık biraz et ekleyebiliriz - bu liste için sahip olduğumuz gerçek geliştirici listesi. Bunun için, bu görünümün kısmisini aşağıdaki gibi genişletiyoruz:

 {{#partial skillView}} <h2> {{ currentSkill }} <button type="button" class="close pull-right" on-click="deselect-skill">&times; CLOSE</button> </h2> {{#each skillDevelopers(currentSkill)}} <div class="panel panel-default"> <div class="panel-body"> {{ this.name }} </div> </div> {{/each}} {{/partial}}

Umarım bu noktada, burada neler olup bittiğine dair bir fikir edinirsiniz: SkillView skillDevelopers skillView sonucu üzerinde yinelenen yeni bir yineleme bölümü ekledik. Dizideki her geliştirici için (bu skillDevelopers işlevi tarafından döndürülür), bir panel oluşturur ve geliştiricinin adını görüntüleriz. Burada {{name}} örtük formunu kullanabileceğimi ve Ractive'in mevcut bağlamdan başlayarak bağlam zincirini arayarak uygun özniteliği bulacağını unutmayın (ki bu bizim durumumuzda {{#each}} ile bağlı geliştirici nesnesidir), ancak Açık sözlü olmayı tercih ederim. Bağlamlar ve referanslar hakkında daha fazla bilgi Ractive belgelerinde mevcuttur.

İşte skillDevelopers() fonksiyonunun uygulaması:

 skillDevelopers: function(skill) { // GET THE SKILL OBJECT FROM THE “DB” skill = skills[skill]; // SAFETY CHECK, RETURN EARLY IN CASE OF UNKNOWN SKILL NAME if (!skill) { return; } // MAP THE DEVELOPER'S IDs (SLUGS) TO THE // ACTUAL DEVELOPER DETAIL OBJECTS return _.map(skill.developers, function(slug) { return developers[slug]; }); }

Her Geliştirici İçin Girişi Genişletme

Artık çalışan bir geliştirici listemiz olduğuna göre, daha fazla ayrıntı ve elbette güzel bir fotoğraf eklemenin zamanı geldi:

 {{#partial skillView}} <h2> {{ currentSkill }} <button type="button" class="close pull-right" on-click="deselect-skill">&times; CLOSE</button> </h2> {{#each skillDevelopers(currentSkill)}} <div class="panel panel-default"> <div class="panel-body media"> <div class="media-left"> <!-- ADD THE PHOTO --> <img class="media-object img-circle" width="64" height="64" src="{{ this.photo }}" alt="{{ this.name }}"> </div> <div class="media-body"> <!-- MAKE THE DEVELOPER'S NAME A HYPERLINK TO THEIR PROFILE --> <a class="h4 media-heading" href="{{ this.url }}" target="_blank"> {{ this.name }}</a> <!-- ADD MORE DETAILS (FROM THEIR PROFILE) --> <p>{{ this.desc }}</p> </div> </div> </div> {{/each}} {{/partial}}

Burada şeylerin Ractive tarafından yeni bir şey yok, ancak Bootstrap özelliklerinin biraz daha ağır kullanımı.

Tıklanabilir Geliştirici Becerileri Listesi Görüntüleme

Şimdiye kadar iyi ilerleme kaydettik, ancak hâlâ eksik olan bir özellik, beceri-geliştirici ilişkisinin diğer yüzü; yani, her geliştiricinin becerilerini göstermek istiyoruz ve bu becerilerin her birinin, bizi o beceri için sonuç görünümüne götüren tıklanabilir bir bağlantı olmasını istiyoruz.

Ama bekleyin… Eminim beceri listesinde zaten aynı şey var. Evet, aslında yapıyoruz. Tıklanabilir beceriler listesindedir, ancak bu, her geliştiricinin beceri kümesinden farklı bir diziden gelir. Yine de bunlar yeterince benzerler ve bu bana o HTML parçasını yeniden kullanmamız gerektiğinin açık bir işareti. Ve bu amaçla, kısmi arkadaşlar bizim dostumuzdur.

(Not: Ractive ayrıca, bileşenler olarak bilinen, bir görünümün yeniden kullanılabilir parçaları için daha gelişmiş bir yaklaşıma sahiptir. Bunlar gerçekten oldukça kullanışlıdır, ancak basitlik adına, bunları şimdi tartışmayacağız.)

Kısmi öğeleri kullanarak bunu nasıl başardığımız aşağıda açıklanmıştır (ve bu arada, bu işlevi tek bir JavaScript kodu satırı eklemeden ekleyebildiğimizi unutmayın!):

 <!-- MAKE THE CLICKABLE SKILL LINK INTO ITS OWN “skill” PARTIAL --> {{#partial skill}} <a href="#" class="label label-primary" on-click="select-skill:{{this}}">{{this}}</a> {{/partial}} {{#partial skillsList}} <div class="row"> <form class="form-horizontal col-xs-6 col-xs-offset-6"> <input type="search" class="form-control" value="{{ skillFilter }}" placeholder="Type part of the skill name here"> </form> </div> <hr> <div class="row"> {{#each skills()}} <!-- USE THE NEW “skill” PARTIAL --> <span class="col-xs-3">{{> skill}}</span> {{/each}} </div> {{/partial}} {{#partial skillView}} <h2> {{ currentSkill }} <button type="button" class="close pull-right" on-click="deselect-skill">&times; CLOSE</button> </h2> {{#each skillDevelopers(currentSkill)}} <div class="panel panel-default"> <div class="panel-body media"> <div class="media-left"> <img class="media-object img-circle" width="64" height="64" src="{{ this.photo }}" alt="{{ this.name }}"> </div> <div class="media-body"> <a class="h4 media-heading" href="{{ this.url }}" target="_blank">{{ this.name }}</a> <p>{{ this.desc }}</p> <p> <!-- ITERATE OVER THE DEVELOPER'S SKILLS --> {{#each this.skills}} <!-- REUSE THE NEW “skill” PARTIAL TO DISPLAY EACH DEVELOPER SKILL AS A CLICKABLE LINK --> {{> skill}}&nbsp; {{/each}} </p> </div> </div> </div> {{/each}} {{/partial}}

“DB”den aldığımız geliştirici nesnesine eklenmiş beceri listesine zaten sahibim, bu yüzden şablonu biraz değiştirdim: Beceri etiketini kısmi hale getiren satırı değiştirdim ve bu kısmı, satırın orijinal olduğu yerde kullandım.

Ardından, geliştiricinin becerilerini yinelediğimde, bu becerilerin her birini tıklanabilir bir bağlantı olarak görüntülemek için aynı yeni bölümü yeniden kullanabilirim. Ayrıca, hatırlarsanız, bu aynı beceri adını geçerek seçme-beceri olayını da temsil eder. Bu, bunu herhangi bir yere dahil edebileceğimiz anlamına gelir (uygun bağlama sahip olarak) ve beceri görünümüne yönlendiren tıklanabilir bir etiket alacağız!

Son Dokunuş — Ön Yükleyici

Tamam, artık temel bir işlevsel uygulamamız var. Temiz ve hızlı çalışıyor, ancak yine de yüklenmesi biraz zaman alıyor. (Bizim durumumuzda, bu kısmen birleştirilmemiş, küçültülmemiş kaynakları kullanmamızdan kaynaklanmaktadır, ancak gerçek dünya uygulamasında ilk verilerin yüklenmesi gibi başka önemli nedenler olabilir).

Son bir adım olarak, Ractive uygulamamızı oluşturur oluşturmaz kaldırılacak bir ön yükleme animasyonu eklemek için size güzel bir numara göstereceğim:

 <div class="container"> <h1>Toptal Search</h1> <div> <div class="progress"> <div class="progress-bar progress-bar-striped active"> Loading... </div> </div> </div> </div>

Peki buradaki sihir nedir? Aslında oldukça basit. Doğrudan kök öğemize biraz içerik ekledim (bu bir Bootstrap animasyonlu ilerleme çubuğu, ancak animasyonlu bir GIF veya herhangi bir şey olabilir). Bence oldukça zekice — betiklerimiz yüklenirken kullanıcı yükleme göstergesini görüyor (JavaScript'e herhangi bir bağımlılığı olmadığı için hemen görüntülenebilir). Ancak, Ractive uygulaması başlatılır başlatılmaz, Ractive oluşturulan şablonla kök öğenin içeriğinin üzerine yazar (ve böylece ön yükleme animasyonunu siler). Bu şekilde, bu efekti sadece bir parça statik HTML ve 0 satır mantık elde edebiliyoruz. Bence bu çok güzel.

Çözüm

Burada neyi başardığımızı ve bunu ne kadar kolay başardığımızı bir düşünün. Oldukça kapsamlı bir uygulamamız var: bir beceri listesi gösterir, bunlar arasında hızlı bir şekilde arama yapılmasına izin verir (ve hatta kullanıcı arama kutusuna yazarken beceri listesinin etkileşimli olarak güncellenmesini destekler), belirli bir beceriye ve geriye doğru gezinmeye izin verir ve listeler Seçilen her beceri için geliştiriciler. Ayrıca, bizi o beceriye sahip geliştiricilerin listesine götürmek için herhangi bir geliştirici tarafından listelenen herhangi bir beceriye tıklayabiliriz. Ve tüm bunlar 80 satırdan az HTML ve 40 satırdan az JavaScript ile. Bana göre, bu oldukça etkileyici ve Ractive'in gücü, zarafeti ve sadeliği hakkında çok şey anlatıyor.

Uygulamanın çalışan bir sürümü burada çevrimiçi olarak mevcuttur ve tam kaynak kodu herkese açıktır ve burada mevcuttur.

Tabii ki, Ractive çerçevesiyle nelerin mümkün olduğuna dair bu makalenin yüzeyini zar zor çizdik. Şimdiye kadar gördüklerinizi beğendiyseniz, Ractive'in 60 saniyelik kurulumuyla başlamanızı ve Ractive'in sunduğu her şeyi kendiniz keşfetmeye başlamanızı şiddetle tavsiye ederim.