Heim  >  Artikel  >  Web-Frontend  >  Einfaches Beispiel für den Einstieg in Backbone.js

Einfaches Beispiel für den Einstieg in Backbone.js

小云云
小云云Original
2018-01-15 10:28:532342Durchsuche

Backbone ist einfach und flexibel und kann sowohl in umfangreichen JS-Anwendungen als auch auf Unternehmenswebsites verwendet werden. Im Vergleich zum React-Design für Ansicht und unidirektionalen Datenfluss verkörpert Backbone die Idee von MVC besser, daher werde ich eine schreiben Einführendes Beispiel dafür, Freunde in Not können sich darauf beziehen, ich hoffe, es kann allen helfen.

Ich habe einen Artikel geschrieben, als ich 2011 zum ersten Mal mit der Verwendung des Front-End-MVC-Frameworks begann. Damals wurden sowohl Knockout als auch Backbone verwendet, aber alle nachfolgenden Projekte verwendeten Backbone, hauptsächlich weil es einfach und flexibel ist Es ist reichhaltig JS Es kann sowohl für Anwendungen als auch für Unternehmenswebsites verwendet werden. Im Vergleich zum React-Design für View und unidirektionalen Datenfluss kann Backbone die Idee von MVC besser verkörpern, daher habe ich ein Einführungsbeispiel dafür geschrieben:

1 Die Struktur ist in 4 unterteilt Abschnitte, die Modell/Ansicht/Sammlung einführen, um Daten von der Fernbedienung abzurufen, sie in der Tabelle anzuzeigen und zu ändern und zu löschen.
2. Der Code ist hauptsächlich der erste Code in jedem Abschnitt Sie können den vollständigen Code kopieren und einfügen, der auf dem vorherigen Code basiert, sodass der neue Inhalt jedes Codes 20 Zeilen (einschließlich geschweifter Klammern) nicht überschreitet Es gibt keine Kommentare für jede Codezeile, aber wichtige Inhalte werden nach spezifischen Anweisungen geschrieben.
4. Die Entwicklungsumgebung ist Chrome und die API von Github wird verwendet, sodass Chrome Daten auch im lokalen Pfad (Pfad) abrufen kann in der Form file://).

0. Einführung

Fast alle Frameworks erfüllen zwei Aufgaben: Zum einen soll sie Ihnen dabei helfen, Code an der richtigen Stelle zu schreiben. Backbone implementiert eine klare MVC-Codestruktur und löst das Problem der Datenmodell- und Ansichtszuordnung. Obwohl alle JS-bezogenen Projekte verwendet werden können, eignet sich Backbone am besten für Szenarien, in denen eine große Menge an Seiteninhalten (hauptsächlich HTML) mit JS generiert werden muss und Benutzer viele Interaktionen mit Seitenelementen haben.

Das Backbone-Objekt hat 5 wichtige Funktionen: Modell/Sammlung/Ansicht/Router/Verlauf. Router und Verlauf sind für Webanwendungen optimiert. Es wird empfohlen, sich zunächst mit pushState-bezogenen Kenntnissen vertraut zu machen. In der Einstiegsphase können Sie nur Modell/Sammlung/Ansicht verstehen. Stellen Sie sich „Model“ als den Kern, „Collection“ als eine Sammlung von Modellen und „View“ als eine Widerspiegelung der Modelländerungen im Frontend vor.

1. Modell

Modell ist der Kern aller JS-Anwendungen. Tatsächlich hat View nicht viel Inhalt und das Verständnis von View ist von geringer Bedeutung . Das Verständnis des Modells ist wichtiger. Der folgende Code implementiert das Abrufen einer Kerninformation von der Github-API und deren Anzeige auf der Seite:

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.1.js"></script>
<script type="text/javascript" src="http://underscorejs.org/underscore-min.js"></script>
<script type="text/javascript" src="http://backbonejs.org/backbone-min.js"></script>

<link href="http://cdn.bootcss.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="stylesheet">
</head>
<body>
 <table id="js-id-gists" class="table">
  <thead><th>description</th><th>URL</th><th>created_at</th></thead>
  <tbody></tbody>
 </table>
 <script type="text/javascript">
 var Gist = Backbone.Model.extend({
  url: 'https://api.github.com/gists/public',
  parse: function (response) {
   return (response[0]);
  }
 }),
  gist = new Gist();

 gist.on('change', function (model) {
  var tbody = document.getElementById('js-id-gists').children[1],
   tr = document.getElementById(model.get('id'));
  if (!tr) {
   tr = document.createElement('tr');
   tr.setAttribute('id', model.get('id'));
  }
  tr.innerHTML = '<td>' + model.get('description') + '</td><td>' + model.get('url') + '</td><td>' + model.get('created_at') + '</td>';
  tbody.appendChild(tr);
 });
 gist.fetch();
 </script>
</body>
</html>
ZEILE4~8: Laden Sie die zu verwendende JS-Bibliothek. Ajax-Anfragen und einige View-Funktionen erfordern jQuery-Unterstützung (oder das Umschreiben von Ajax-/View-Funktionen); der Code von Backbone basiert auf Underscore (oder wird durch Lo-Dash ersetzt); nur weil der Standardstil zu hässlich ist...

ZEILE16~22: Erstellen Sie ein Modell und instanziieren Sie es. URL ist die Adresse der Datenquelle (API-Schnittstelle), und Parse wird zum Verarbeiten der zurückgegebenen Daten verwendet. Was tatsächlich zurückgegeben wird, ist ein Array, hier nehmen wir das erste Objekt.

LINE24~33: Änderungsereignis binden. Ich habe View noch nicht verwendet, daher muss ich mich selbst um den HTML-Code kümmern. Diese 10 Codezeilen dienen hauptsächlich der Verwendung von get (model.get), und andere Funktionen werden später mit View implementiert.

ZEILE34: Abruf ausführen. Rufen Sie Daten von der Fernbedienung ab und das Änderungsereignis wird ausgelöst, nachdem die Daten abgerufen wurden. Sie können die Synchronisierungsmethode überschreiben.

Öffnen Sie die Chrome-Konsole, geben Sie „gist“ ein. Sie können die vom Modell erhaltenen Attribute sehen:

Das Modell stellt Daten und Daten bereit. verwandte Logik. Bei den im obigen Bild ausgegebenen Attributen handelt es sich um Daten. Die Funktionen „fetch/parse/get/set“ umfassen Escape/Unset/Clear/Destroy. Sie können den Zweck grob anhand des Funktionsnamens verstehen. Es gibt auch eine sehr häufig verwendete Validierungsfunktion, die zur Datenüberprüfung während Setz-/Speichervorgängen verwendet wird. Ein Fehler bei der Überprüfung löst das ungültige Ereignis aus:

/* 替换之前代码的JS部分(LINE16~34) */
 var Gist = Backbone.Model.extend({
  url: 'https://api.github.com/gists/public',
  parse: function (response) {
   return (response[0]);
  },
  defaults: {
   website: 'dmyz'
  },
  validate: function (attrs) {
   if (attrs.website == 'dmyz') {
    return 'Website Error';
   }
  }
 }),
  gist = new Gist();

 gist.on('invalid', function (model, error) {
  alert(error);
 });
 gist.on('change', function (model) {
  var tbody = document.getElementById('js-id-gists').children[1],
   tr = document.getElementById(model.get('id'));
  if (!tr) {
   tr = document.createElement('tr');
   tr.setAttribute('id', model.get('id'));
  }
  tr.innerHTML = '<td>'+ model.get('description') +'</td><td>'+ model.get('url') +'</td><td>'+ model.get('created_at') +'</td>';
  tbody.appendChild(tr);
 });
 gist.save();
Im Vergleich zum vorherigen Code gibt es 4 Änderungen :

ZEILE7~9: Standardeinstellungen hinzugefügt. Wenn das Attribut keine Website enthält (beachten Sie, dass der Website-Wert nicht leer ist), wird der Website-Wert auf dmyz gesetzt.

ZEILE10~14: Validierungsfunktion hinzufügen. Wenn der Website-Wert dmyz ist, wird das ungültige Ereignis ausgelöst.
ZEILE18~20: Ungültiges Ereignis binden, Fehler durch Warnung zurückgegeben.
ZEILE31: Kein Abruf, Vorgang direkt speichern.

Da kein Abruf erfolgt, werden die Daten nicht auf der Seite angezeigt. Wenn der Speichervorgang ausgeführt wird, wird die Validierungsfunktion aufgerufen. Wenn die Überprüfung fehlschlägt, wird das ungültige Ereignis ausgelöst und eine Warnung löst einen Fehler aus. Gleichzeitig initiiert der Speichervorgang auch eine PUT-Anfrage an die URL des Modells. Die Github-API verarbeitet PUT nicht, sodass ein 404-Fehler zurückgegeben wird.

Geben Sie gist.set(‘description’, ‘demo’) in die Konsole ein und Sie können sehen, dass sich auch die Seitenelemente entsprechend ändern. Führen Sie gist.set('description', gist. previous('description')) aus, um den vorherigen Wert wiederherzustellen. Dies ist die Zuordnung zwischen Modell und Ansicht. Ich werde sie jetzt noch selbst implementieren. Im nächsten Abschnitt werde ich die Ansicht von Backbone verwenden.

2. Ansicht

Verwenden Sie die Ansicht von Backbone, um die Teile ZEILE24~33 des vorherigen Codes neu zu schreiben:

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.1.js"></script>
<script type="text/javascript" src="http://underscorejs.org/underscore-min.js"></script>
<script type="text/javascript" src="http://backbonejs.org/backbone-min.js"></script>

<link href="http://cdn.bootcss.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="stylesheet">
</head>
<body>
 <table id="js-id-gists" class="table">
  <thead><th>description</th><th>URL</th><th>created_at</th><th></th></thead>
  <tbody></tbody>
 </table>
 <script type="text/javascript">
 var Gist = Backbone.Model.extend({
  url: 'https://api.github.com/gists/public',
  parse: function (response) {
   return response[0];
  }
 }),
  gist = new Gist();

 var GistRow = Backbone.View.extend({
  el: 'tbody',
  MODEL: gist,
  events: {
   'click a': 'replaceURL'
  },
  replaceURL: function () {
   this.MODEL.set('url', 'http://dmyz.org');
  },
  initialize: function () {
   this.listenTo(this.MODEL, 'change', this.render);
  },
  render: function () {
   var model = this.MODEL,
    tr = document.createElement('tr');
   tr.innerHTML = '<td>' + model.get('description') + '</td><td>' + model.get('url') + '</td><td>' + model.get('created_at') + '</td><td><a href="javascript:void(0)" rel="external nofollow" rel="external nofollow" rel="external nofollow" >®</a></td>';
   this.el.innerHTML = tr.outerHTML;
   return this;
  }
 });
 var tr = new GistRow();
 gist.fetch();
 </script>
</body>
</html>

LINE25: 所有的View都是基于DOM的,指定el会选择页面的元素,指定tagName会创建相应的DOM,如果都没有指定会是一个空的p。
LINE27~32: 绑定click事件到a标签,replaceURL函数会修改(set)url属性的值。
LINE33~35: View的初始化函数(initialize),监听change事件,当Model数据更新时触发render函数。
LINE36~42: render函数。主要是LINE41~42这两行,把生成的HTML代码写到this.el,返回this。
LINE44: 实例化GistRow,初始化函数(initialize)会被执行。

点击行末的a标签,页面显示的这条记录的URL会被修改成http://dmyz.org。

这个View名为GistRow,选择的却是tbody标签,这显然是不合理的。接下来更改JS代码,显示API返回的30条数据:

/* 替换之前代码的JS部分(LINE16~45) */
 var Gist = Backbone.Model.extend(),
  Gists = Backbone.Model.extend({
   url: 'https://api.github.com/gists/public',
   parse: function (response) {
    return response;
   }
  }),
  gists = new Gists();

 var GistRow = Backbone.View.extend({
  tagName: 'tr',
  render: function (object) {
   var model = new Gist(object);
   this.el.innerHTML = '<td>' + model.get('description') + '</td><td>'+ model.get('url') + '</td><td>' + model.get('created_at') + '</td><td></td>'
   return this;
  }
 });

 var GistsView = Backbone.View.extend({
  el: 'tbody',
  model: gists,
  initialize: function () {
   this.listenTo(this.model, 'change', this.render);
  },
  render: function () {
   var html = '';
   _.forEach(this.model.attributes, function (object) {
    var tr = new GistRow();
    html += tr.render(object).el.outerHTML;
   });
   this.el.innerHTML = html;
   return this;
  }
 });
 var gistsView = new GistsView();
 gists.fetch();

LINE2~9: 创建了两个Model(Gist和Gists),parse现在返回完整Array而不只是第一条。
LINE11~18: 创建一个tr。render方法会传一个Object来实例化一个Gist的Model,再从这个Model里get需要的值。
LINE26~34: 遍历Model中的所有属性。现在使用的是Model而不是Collection,所以遍历出的是Object。forEach是Underscore的函数。

Backbone的View更多的是组织代码的作用,它实际干的活很少。View的model属性在本节第一段代码用的是大写,表明只是一个名字,并不是说给View传一个Model它会替你完成什么,控制逻辑还是要自己写。还有View中经常会用到的template函数,也是要自己定义的,具体结合哪种模板引擎来用就看自己的需求了。

这段代码中的Gists比较难操作其中的每一个值,它其实应该是Gist的集合,这就是Backbone的Collection做的事了。

3. Collection

Collection是Model的集合,在这个Collection中的Model如果触发了某个事件,可以在Collection中接收到并做处理。第2节的代码用Collection实现:

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.1.js"></script>
<script type="text/javascript" src="http://underscorejs.org/underscore-min.js"></script>
<script type="text/javascript" src="http://backbonejs.org/backbone-min.js"></script>

<link href="http://cdn.bootcss.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="stylesheet">
</head>
<body>
 <table id="js-id-gists" class="table">
  <thead><th>description</th><th>URL</th><th>created_at</th><th></th></thead>
  <tbody></tbody>
 </table>
 <script type="text/javascript">
 var Gist = Backbone.Model.extend(),
  Gists = Backbone.Collection.extend({
   model: Gist,
   url: 'https://api.github.com/gists/public',
   parse: function (response) {
    return response;
   }
  }),
  gists = new Gists();

 var GistRow = Backbone.View.extend({
  tagName: 'tr',
  render: function (model) {
   this.el.innerHTML = '<td>' + model.get('description') + '</td><td>'+ model.get('url') + '</td><td>' + model.get('created_at') + '</td><td></td>'
   return this;
  }
 });

 var GistsView = Backbone.View.extend({
  el: 'tbody',
  collection: gists,
  initialize: function () {
   this.listenTo(this.collection, 'reset', this.render);
  },
  render: function () {
   var html = '';
   _.forEach(this.collection.models, function (model) {
    var tr = new GistRow();
    html += tr.render(model).el.outerHTML;
   });
   this.el.innerHTML = html;
   return this;
  }
 });
 var gistsView = new GistsView();
 gists.fetch({reset: true});
 </script>
</body>
</html>

LINE17~23: 基本跟第2节的第2段代码一样。把Model改成Collection,指定Collection的Model,这样Collectio获得返回值会自动封装成Model的Array。
LINE38: Collection和Model不同,获取到数据也不会触发事件,所以绑定一个reset事件,在之后的fetch操作中传递{reset: true}。
LINE42~45: 从Collection从遍历Model,传给GistRow这个View,生成HTML。

Collection是Backbone里功能最多的函数(虽然其中很多是Underscore的),而且只要理解了Model和View的关系,使用Collection不会有任何障碍。给Collection绑定各种事件来实现丰富的交互功能了,以下这段JS代码会加入删除/编辑的操作,可以在JSBIN上查看源代码和执行结果。只是增加了事件,没有什么新内容,所以就不做说明了,附上JSBIN的演示地址:http://jsbin.com/jevisopo/1

/* 替换之前代码的JS部分(LINE16~51) */
 var Gist = Backbone.Model.extend(),
  Gists = Backbone.Collection.extend({
   model: Gist,
   url: 'https://api.github.com/gists/public',
   parse: function (response) {
    return response;
   }
  }),
  gists = new Gists();

 var GistRow = Backbone.View.extend({
  tagName: 'tr',
  render: function (model) {
   this.el.id = model.cid;
   this.el.innerHTML = '<td>' + model.get('description') + '</td><td>'+ model.get('url') + '</td><td>' + model.get('created_at') + '</td><td><a href="javascript:void(0)" rel="external nofollow" rel="external nofollow" rel="external nofollow" class="js-remove">X</a> <a href="javascript:void(0)" rel="external nofollow" rel="external nofollow" rel="external nofollow" class="js-edit">E</a> </td>'
   return this;
  }
 });

 var GistsView = Backbone.View.extend({
  el: 'tbody',
  collection: gists,
  events: {
   'click a.js-remove': function (e) {
    var cid = e.currentTarget.parentElement.parentElement.id;
    gists.get(cid).destroy();
    gists.remove(cid);
   },
   'click a.js-edit': 'editRow',
   'blur td[contenteditable]': 'saveRow'
  },
  editRow: function (e) {
   var tr = e.currentTarget.parentElement.parentElement,
    i = 0;

   while (i < 3) {
    tr.children[i].setAttribute('contenteditable', true);
    i++;
   }
  },
  saveRow: function (e) {
   var tr = e.currentTarget.parentElement,
    model = gists.get(tr.id);

   model.set({
    'description' : tr.children[0].innerText,
    'url': tr.children[1].innerText,
    'created_at': tr.children[2].innerText
   });
   model.save();
  },
  initialize: function () {
   var self = this;
   _.forEach(['reset', 'remove', 'range'], function (e) {
    self.listenTo(self.collection, e, self.render);
   });
  },
  render: function () {
   var html = '';
   _.forEach(this.collection.models, function (model) {
    var tr = new GistRow();
    html += tr.render(model).el.outerHTML;
   });
   this.el.innerHTML = html;
   return this;
  }
 });
 var gistsView = new GistsView();
 gists.fetch({reset: true});

Afterword

虽然是入门范例,但因为篇幅有限,有些基本语言特征和Backbone的功能不可能面面俱到,如果还看不懂肯定是我漏掉了需要解释的点,请(在Google之后)评论或是邮件告知。

Backbone不是jQuery插件,引入以后整个DOM立即实现增删改查了,也做不到KnockoutJS/AnglarJS那样,在DOM上做数据绑定就自动完成逻辑。它是将一些前端工作处理得更好更规范,如果学习前端MVC的目的是想轻松完成工作,Backbone可能不是最佳选择。如果有一个项目,100多行HTML和1000多行JS,JS主要都在操作页面DOM(如果讨厌+号连接HTML还可以搭配React/JSX来写),那就可以考虑用Backbone来重写了,它比其他庞大的MVC框架要容易掌握得多,作为入门学习也是非常不错的。

相关推荐:

使用Backbone.js创建一个增删改查表的实例代码

javascript - 关于backbone.js里的model.set和model.get

Backbone.js中的集合详解_其它

Das obige ist der detaillierte Inhalt vonEinfaches Beispiel für den Einstieg in Backbone.js. 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