Читал на Backbone.js, где они приводят этот пример.

var Sidebar = Backbone.Model.extend({
  promptColor: function() {
    var cssColor = prompt("Please enter a CSS color:");
    this.set({color: cssColor});
  }
});

window.sidebar = new Sidebar;

sidebar.on('change:color', function(model, color) {
  $('#sidebar').css({background: color});
});

sidebar.set({color: 'white'});

sidebar.promptColor();

Подсказка запрашивает цвет, когда вы вводите его, цвет боковой панели меняется. Мой вопрос: почему я должен предпочесть приведенный выше код коду ниже? Я думаю, что это как-то связано со структурой кода, но я не могу точно сказать, почему. Это потому, что этот пример слишком прост, а преимущества написания приведенного выше кода появляются только тогда, когда приложение становится большим?

Игнорировать магистральный код для инициализации начального цвета и вызова promptColor(), я оставил его там для контекста.

function promptColor(){
    var cssColor = prompt("please enter a css color:");
    $('#sidebar').css({background:cssColor})
}
1
Eric Guan 16 Дек 2015 в 17:59

3 ответа

Лучший ответ

Прежде всего, данный пример плохой, демонстрирующий DOM манипуляцию внутри модели ..! Нет, это не то место, где вы манипулируете DOM.

Ключевым моментом, который следует отметить, является то, что магистраль придает структуру вашему приложению, позволяет легко разделять проблемы.

Если вы видите приведенный ниже пример (снова плохой пример с боковой панелью ), логика представления полностью обрабатывается экземпляром Backbone.View .

  • Это независимый экземпляр, вы можете создать их количество
  • Backbone создал для вас элемент DOM с указанными свойствами
  • Backbone позволил очень легко настроить делегированные обработчики событий
  • Backbone позволил очень легко определить код инициализации, который будет запускаться при создании экземпляра боковой панели.
  • Нам не нужно проходить весь DOM, и вероятность конфликтов очень мала, так как мы работаем с каждым элементом представления внутри него.
  • Вы можете просто сделать instance.remove(), чтобы удалить обработчики событий и элемент из DOM
  • и многое другое больше

Состояние компонента и связанные данные хранятся в экземплярах Backbone.Model .

  • Позволяет определить начальное состояние
  • Может легко настроить логику инициализации
  • События облегчают обработку изменений в данных
  • Позволяет проверить изменения данных
  • Позволяет легко синхронизировать данные с бэкэндом
  • и многое другое больше
var Color = Backbone.Model.extend({
  defaults: {
    color: 'white',
    accepted: ['white', 'red', 'green', 'blue']
  },
  validate: function(attrs) {
    if (this.get("accepted").indexOf(attrs.color) < 0)
      return new Error();
  }
});
var Sidebar = Backbone.View.extend({
  attributes: {
    class: 'sidebar'
  },
  initialize: function() {
    this.listenTo(this.model, 'change:color', this.switchColor);
    this.render();
  },
  events: {
    'input .color': 'updateColor',
    'click .close': 'remove'
  },
  render: function() {
    this.$el.append($('#sidebar').html());
    return this;
  },
  updateColor: function(e) {
    this.model.set({
      color: $(e.target).val()
    }, {
      validate: true
    });
  },
  switchColor: function(model, color) {
    this.$el.css({
      background: color
    });
  }
});

for (var i = 0; i < 3; i++) {
  $('body').append(new Sidebar({
    model: new Color()
  }).el);
}
* {
  margin: 0;
  padding: 0;
}
html,
body {
  height: 100%
}
.sidebar {
  display: inline-block;
  box-sizing: border-box;
  position: relative;
  height: 100%;
  padding: 5px 15px 5px 0;
  margin: 0 2px;
  border: 5px solid dodgerblue
}
.close {
  display: inline-block;
  position: absolute;
  top: 5px;
  right: 0;
  height: 18px;
  text-decoration:none;
  border: 0px solid grey;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.2.3/backbone-min.js"></script>
<script type="text/template" id="sidebar">
  <input type="text" class="color" placeholder="enter bg color... red, green, blue"/>
  <a href="#" class="close">&#10006;</a>
</script>

Конечно, вы можете напрямую изменить цвет, не устанавливая его в модели в этом конкретном примере, суть в том, чтобы показать, как вы разделяете проблемы компонентов в реальных приложениях.

Работа моделей заключается в том, чтобы хранить данные и постоянно проверять их правильность. Просмотр представляет данные пользователю и позволяет ему работать с ним. Модель выступает источником истины.

Если вы используете обычный js, вы обнаружите, что ваши данные и DOM тесно связаны между собой, и вам придется писать собственную логику для огромного количества вещей, которые магистраль предоставляет из коробки ... как это система событий ... router ... collection ... sync API .. ( и мы не используем ни одного из них, кроме крошечного использования системы событий, поэтому его плохой пример )


Чтобы ответить на ваш вопрос: «Это потому, что этот пример слишком прост» - Да . Люди обычно не идут за рамками MV * js, чтобы настроить подсказку ... Это похоже на ручную гранату, чтобы открыть пластиковую дверь, как упоминал Александр.

Вы увидите, что магистраль превосходна, когда вы захотите выполнить операции CRUD, обработать маршрутизацию, связаться с бэкендом и т. Д. Например, для отправки последнего цвета ( будь то любые данные ) все, что вам нужно сделать, это добавить Свойство url для объявления модели и вызов model.save(). Как это круто..?

2
T J 16 Дек 2015 в 17:21

Для этого конкретного примера, как он упоминался здесь, это не имеет никакого смысла, но, скажем, если вы хотите синхронизировать свою коллекцию элементов, таких как [{id: 1, body: "Hello World"}, {id: 2, body: "Hello World!"}], получите новые элементы, которые появились в бэкэнде, и быстро отобразите их с помощью шаблона, который вы определены, или, скажем, обновить некоторый элемент и хотите синхронизировать его с бэкэндом. Это гораздо проще сделать с такими фреймворками, как Backbone.js.

На мой взгляд, это не помешает вам, конечно, из кода спагетти, потому что все зависит от вас. Но это может помочь вам разделить логику и упростить чтение для членов вашей команды.

Чтобы лучше понять Backbone.js, я бы порекомендовал вам ознакомиться с этим руководством: http: // backbonejs. орг / документы / todos.html

0
rudkovskyi 16 Дек 2015 в 15:23

Для этого простого примера не имеет смысла использовать фреймворк. Это похоже на использование IDE для написания сценария из 10 строк или использование гранаты для открытия двери. Возможно, вы захотите взглянуть на некоторые проекты, использующие магистраль, или лучше всего подумать о более крупной задаче, а затем придумать реализацию магистрали против vanillaJS.

Исходя из моего личного опыта, я часто сталкиваюсь со сложностями всего проекта - вам нужно найти подходящие инструменты для вашей работы, или вы получите спагетти-код или монолитную структуру для простых задач.

0
Alexander Kludt 16 Дек 2015 в 15:05