Heim >Web-Frontend >js-Tutorial >Ein genauerer Blick auf CanJS: Teil 2

Ein genauerer Blick auf CanJS: Teil 2

WBOY
WBOYOriginal
2023-08-31 11:33:17770Durchsuche

Dies ist der zweite Teil einer dreiteiligen Serie, in der Sie lernen, wie Sie mit CanJS und jQuery eine Kontaktmanager-Anwendung in JavaScript erstellen. Nach Abschluss dieses Tutorials verfügen Sie über alles, was Sie zum Erstellen Ihrer eigenen JavaScript-Anwendungen mit CanJS benötigen!

Im ersten Teil haben Sie das Modell, die Ansichten und die Steuerelemente erstellt, die zum Anzeigen von Kontakten erforderlich sind, und zwar mithilfe von Vorrichtungen, die einen REST-Dienst simulierten.

In diesem Abschnitt werden Sie:

  • Erstellen Sie Steuerelemente und Ansichten, um Kategorien anzuzeigen.
  • Verwenden Sie Steuerelemente, um Ereignisse abzuhören.
  • Verwenden Sie Routing, um Kontakte zu filtern.

Im ersten Teil werden Sie Quelldateien hinzufügen. Wenn Sie dies noch nicht getan haben, informieren Sie sich bitte zuerst. Ich werde hier sein, wenn du bereit bist.


Routen festlegen

Routing hilft bei der Verwaltung des Browserverlaufs und des Clientstatus in Single-Page-JavaScript-Anwendungen.

Routing hilft bei der Verwaltung des Browserverlaufs und des Clientstatus in Single-Page-JavaScript-Anwendungen. Der Hash in der URL enthält Eigenschaften, die die Anwendung liest und schreibt. Verschiedene Teile der Anwendung können auf diese Änderungen warten und entsprechend reagieren, wobei häufig Teile der aktuellen Seite aktualisiert werden, ohne eine neue Seite zu laden.

can.route 是一个特殊的可观察对象,它更新并响应 window.location.hash 中的更改。使用 can.route 将 URL 映射到属性,从而生成漂亮的 URL,例如 #!filter/all。如果没有定义路由,则哈希值只会序列化为 URL 编码表示法,如 #!category=all.

In dieser App wird Routing verwendet, um Kontakte nach Kategorien zu filtern. Fügen Sie Ihrer contacts.js-Datei den folgenden Code hinzu:

can.route( 'filter/:category' )
can.route('', {category: 'all' })

Die erste Zeile erstellt eine Zeile mit category 属性的路由,您的应用程序将能够读取和写入该属性。第二行创建一个默认路由,将 category 属性设置为 all.


Modellinstanzliste verwenden

A Model.List 是模型实例的可观察数组。当您定义 Model (如 Contact)时,会自动创建该类型模型的 Model.List 。我们可以扩展这个创建的 Model.List zum Hinzufügen von Hilfsfunktionen, die auf einer Liste von Modellinstanzen arbeiten.

Contact.List erfordert zwei Hilfsfunktionen, um die Kontaktliste zu filtern und zu melden, wie viele Kontakte sich in jeder Kategorie befinden. Fügen Sie dies zu Contact.List 将需要两个辅助函数来过滤联系人列表并报告每个类别中有多少联系人。将其添加到 contacts.js 紧跟在 Contact direkt nach dem Kontakt-Modell hinzu:

Contact.List = can.Model.List({
  filter: function(category){
    this.attr('length');
    var contacts = new Contact.List([]);
    this.each(function(contact, i){
      if(category === 'all' || category === contact.attr('category')) {
        contacts.push(contact)
      }
    })
    return contacts;
  },
  count: function(category) {
    return this.filter(category).length;
  }
});

Die beiden Hilfsfunktionen hier sind:

  • filter() 循环访问列表中的每个联系人,并返回类别内联系人的新 Contact.Listthis.attr('length') ist hier enthalten. Wenn wir diesen Helfer in einer Ansicht verwenden, richtet EJS die Live-Bindung ein.
  • count() 使用 filter() 辅助函数返回类别中的联系人数量。由于 this.attr('length')filter() Wenn wir diesen Helfer in einer Ansicht verwenden, richtet EJS die Live-Bindung ein.

Wenn Sie Helfer in EJS verwenden, verwenden Sie attr() für eine Liste oder Instanzeigenschaft, um die Live-Bindung festzulegen.


Kontakte filtern

Als nächstes ändern Sie contactsList.ejs 视图,以根据哈希中的类别属性过滤联系人。在 contactsList.ejs 视图中,将传递给 list() 帮助器的参数更改为 contacts.filter(can.route.attr('category')). Wenn Sie fertig sind, sollte Ihre EJS-Datei so aussehen:

<ul class="unstyled clearfix">
  <% list(contacts.filter(can.route.attr('category')), function(contact){ %>
    <li class="contact span8" <%= (el)-> el.data('contact', contact) %>>
      <div class="">
        <%== can.view.render('contactView', {contact: contact, categories: categories}) %>
      </div>
    </li>
  <% }) %>
</ul>

In der zweiten Zeile wird filter() mit der aktuellen Kategorie in can.route aufgerufen. Da Sie can.route 中的当前类别调用 filter()。由于您在 filter()can.route 中使用了 attr() in filter() und can.route verwendet haben, richtet EJS Live-Bindungen ein, um Ihre Benutzeroberfläche neu zu rendern, wenn sich eine davon ändert.

Jetzt sollten Sie sich der Kraft der Live-Bindung bewusst sein. Durch eine leichte Anpassung der Ansicht ist die Benutzeroberfläche der App nun nicht nur vollständig mit der Kontaktliste, sondern auch mit den in der Route definierten Kategorieattributen synchronisiert.


Kategorien anzeigen

Kontakte werden gefiltert, wenn sich das Kategorieattribut im Hash ändert. Jetzt benötigen Sie eine Möglichkeit, alle verfügbaren Kategorien aufzulisten und den Hash zu ändern.

Erstellen Sie zunächst eine neue Ansicht, um die Liste der Kategorien anzuzeigen. Speichern Sie diesen Code als filterView.ejsviews im Ordner:

<ul class="nav nav-list">
  <li class="nav-header">Categories</li>
  <li>
    <a href="javascript://" data-category="all">All (<%= contacts.count('all') %>)</a>
  </li>
  <% $.each(categories, function(i, category){ %>
    <li>
      <a href="javascript://" data-category="<%= category.data %>"><%= category.name %> (<%= contacts.count(category.data) %>)</a>
    </li>
  <% }) %>
</ul>

Schauen wir uns ein paar Zeilen aus diesem Code an und sehen, was sie bewirken:

<% $.each(categories, function(i, category){ %>

$.each Durchlaufen Sie die Kategorien und führen Sie für jede Kategorie einen Rückruf aus.

<a href="javascript://" data-category="<%= category.data %>"><%= category.name %> (<%= contacts.count(category.data) %>

每个链接都有一个 data-category 属性,该属性将被拉入 jQuery 的数据对象中。稍后,可以使用 <a></a> 标记上的 .data('category') 来访问该值。类别的名称和联系人数量将用作链接测试。实时绑定是根据联系人数量设置的,因为 count() 调用 filter() 其中包含 this.attr('length')


使用 can.Control 监听事件

创建实例时,控件会自动绑定看起来像事件处理程序的方法。事件处理程序的第一部分是选择器,第二部分是您要侦听的事件。选择器可以是任何有效的 CSS 选择器,事件可以是任何 DOM 事件或自定义事件。因此,像 'a click' 这样的函数将监听控件元素内任何 <a></a> 标记的点击。

Control 使用事件委托,因此您不必担心在 DOM 更改时重新绑定事件处理程序。


显示类别

通过将此代码添加到 contacts.js 紧随 Contacts 控件之后来创建管理类别的控件:

Filter = can.Control({
  init: function(){
    var category = can.route.attr('category') || "all";
    this.element.html(can.view('filterView', {
      contacts: this.options.contacts,
      categories: this.options.categories
    }));
    this.element.find('[data-category="' + category + '"]').parent().addClass('active');
  },
  '[data-category] click': function(el, ev) {
    this.element.find('[data-category]').parent().removeClass('active');
    el.parent().addClass('active');
    can.route.attr('category', el.data('category'));
  }
});

让我们检查一下您刚刚创建的“Filter”控件中的代码:

this.element.html(can.view('filterView', {
  contacts: this.options.contacts,
  categories: this.options.categories
}));

就像在 Contacts 控件中一样,init() 使用 can.view() 来呈现类别,并使用 html() 将其插入到控件的元素中。

this.element.find('[data-category="' + category + '"]').parent().addClass('active');

查找与当前类别相对应的链接,并将“active”类添加到其父元素。

'[data-category] click': function(el, ev) {

监听与选择器 [data-category] 匹配的任何元素上的 click 事件。

this.element.find('[data-category]').parent().removeClass('active');
el.parent().addClass('active');

从所有链接中删除“活动”类,然后向单击的链接添加“活动”类。

can.route.attr('category', el.data('category'));

使用 jQuery 数据对象中所单击的 <a></a> 的值更新 can.route 中的类别属性。


初始化过滤器控件

就像第一部分中的 Contacts 控件一样,您需要创建 Filter 控件的新实例。更新您的文档就绪函数,如下所示:

$(document).ready(function(){
  $.when(Category.findAll(), Contact.findAll()).then(function(categoryResponse, contactResponse){
    var categories = categoryResponse[0], 
      contacts = contactResponse[0];

    new Contacts('#contacts', {
      contacts: contacts,
      categories: categories
    });
    new Filter('#filter', {
      contacts: contacts,
      categories: categories
    });
  });
})

通过此更改,将在 #filter 元素上创建 Filter 控件的实例。它将传递联系人和类别列表。

现在,当您在浏览器中运行应用程序时,您将能够通过单击右侧的类别来过滤联系人:

Ein genauerer Blick auf CanJS: Teil 2


总结

这就是第二部分的全部内容!以下是我们所取得的成就:

  • 创建了一个用于侦听事件并管理类别的控件
  • 设置路由以按类别过滤联系人
  • 调整了您的视图,以便实时绑定使您的整个 UI 与数据层保持同步

在第三部分中,您将更新现有控件以允许编辑和删除联系人。您还将创建一个新的控件和视图,以便您添加新的联系人。

迫不及待想了解更多信息?该系列的第三部分已发布在这里!

Das obige ist der detaillierte Inhalt vonEin genauerer Blick auf CanJS: Teil 2. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn