21.10.2015, 13:45
|
|
Кандидат Javascript-наук
|
|
Регистрация: 28.05.2015
Сообщений: 116
|
|
Backbone порядок наступления событий
Сижу разбираюсь в backbone.js ...
Есть такой код:
var Person = Backbone.Model.extend({
defaults: {
name: ''
},
initialize: function () {
this.on('change:name', function () {
console.log('event1: ' + this.get('name'));
});
this.on('change', function () {
console.log('event2: ' + this.get('name'));
});
this.on('change:name', function () {
console.log('event3: ' + this.get('name'));
});
}
});
var person1 = new Person();
person1.set('name': 'Malcolm');
выводит
event1: Malcolm
event3: Malcolm
event2: Malcolm <-- Выводит в последнюю очередь
Т.е. более конкретно определенное событие при прочих равных обрабатывается ранее?
Это особенность фреймворка или чего-то другого?
Или тут имеет место некий аналог "всплытия" события для модели?
|
|
25.10.2015, 21:24
|
Кандидат Javascript-наук
|
|
Регистрация: 16.02.2012
Сообщений: 109
|
|
Лучше пример приведи, где это может вызвать проблему. Вообще бэкбоне достаточно гибкий. Если грамотно научить модели слушать события и параметры друг у друга, конфликтов можно избежать. Я в своем коде коде создаю обычно материнский класс, который регистрирует все события - нажатия мышей и прочее, а другие классы его прослушивают и получают команды, когда можно что-то сделать, когда нет.
|
|
25.10.2015, 22:22
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,120
|
|
мысли вслух: поставили функции на два события - сначала сработали функции от события 'change:name' потом выше от просто 'change'
|
|
26.10.2015, 10:28
|
|
Кандидат Javascript-наук
|
|
Регистрация: 28.05.2015
Сообщений: 116
|
|
Вопрос был: Почему так?
А не: У меня проблема с этим.../ Как сделать что-то...
Думал, может кто на форуме владеет достаточными знаниями по сабжу, чтобы просветить.
Сообщение от vuler
|
Я в своем коде коде создаю обычно материнский класс, который регистрирует все события - нажатия мышей и прочее, а другие классы его прослушивают и получают команды, когда можно что-то сделать, когда нет.
|
И что играет роль 'материнского класса"?
view, collection или model (подозреваю, что не два последних)?
И пример кода можно глянуть для предлагаемого паттерна?
Последний раз редактировалось armidoll, 26.10.2015 в 11:27.
|
|
28.10.2015, 23:00
|
Кандидат Javascript-наук
|
|
Регистрация: 16.02.2012
Сообщений: 109
|
|
Каждый пишет код как ему нравится. Я раньше разделял view и model у одного и того же элемента управления на странице, но устанавливать обработчики событий в view не очень удобно - нет гибкости у селекторов. Приходится использовать delegate, который и в модели встает хорошо, в конечном итоге использую одни model-и и коллекции. Знаю что возможно не использую весь потенциал движка, но того что дает объект model мне вполне хватает на все что необходимо. Когда код становится большим, может появиться неразбериха, куда ты воткнул ту или иную функцию - в модель или ее отображение.
Что касается примера, то движок я переписываю, вот набросок небольшой, там смысл будет понятен в принципе
Big_model=Backbone.Model.extend({
elid:'',
set_shapes:function(){
this.shapes_block=$(this.el).find('>.shapes');
var that=this;
this.shapes_block.find('>*').each(function(){
var name=$(this).attr('name');
that['shape_'+name]=$(this).children().clone();
})
},
set_data:function(){
this.data_block=$(this.el).find('>.data');
var that=this;
this.data_block.find('>*').each(function(){
var name=$(this).attr('name');
// console.log($(this).html())
if (!full_null($(this).html())){
switch (name){
case 'ajax':
that.ajax_param=JSON.parse($(this).html());
default:
that[name]=JSON.parse($(this).html());
}
}else
that[name]='';
})
},
set_elid:function(){
this.elid=elid;
this.el.attr('elid',this.elid)
elid++;
},
set_param:function(options){
this.el=options.el;
this.parent=options.parent;
this.set_shapes();
this.set_data();
this.set_elid();
this.set_def_el();
this.set_cus_events();
},
set_def_el:function(){//пользовательские элементы
},
set_cus_events:function(){//Установка событий
},
})
App=Big_model.extend({//Модель приложения основная
bm:{},//Массив моделей
initialize:function(){
this.set_param({el:$('body')});
this.ajax=new Ajax();
console.log('Арр загружен');
},
init_bm_scan:function(){
var that=this;
this.el.find('.big_model').each(function(){
that.init_bm($(this));
})
},
init_bm:function(model){
if (!fn(model.attr('elid'))) return;//Объект ранее уже инициализировался и ему присвоен id;
var type=model.attr('type');
var class_name=window[type];
if (this.bm[type]== undefined) this.bm[type]=[];
this.bm[type].push(new class_name({el:model}));
},
init_bm_sub:function(options){
var type=options.el.attr('type');
// console.log(type)
var class_name=window[type];
return new class_name(options)
}
})
Ajax=Big_model.extend({
ajax_proceed_url:'php/ajax_proceed.php',
send_st:function(param){
var result=''
$.ajax({
type: 'POST', dataType: 'json',
url:MAIN_URL+this.ajax_proceed_url,async: false,
data:({data:param.data,task:param.task,class:param.target.class,file:param.target.file}),
success: function(data){
result=data;
},
error: function(jqXHR, textStatus, errorThrown){
console.log(textStatus);
}
});
return result;
},
})
$(window).load(function(){
$(document).ready(function() {
elid=1;
app=new App;
app.init_bm_scan();
})
})
|
|
29.10.2015, 01:42
|
|
Кандидат Javascript-наук
|
|
Регистрация: 28.05.2015
Сообщений: 116
|
|
Ok. Спасибо за пример.
Я не скрываю, что я еще очень юный javascript и Backbone падаван, но в такой архитектуре приложения, когда обработка событий генерируемых пользователем находится в model (тут ведь, например, обрабатывается клик мыши на какую-нибудь кнопку "добавить"?)
set_cus_events:function(){//Установка событий
}
а не во view, нет противоречия самой концепции Backbone как решения для отделения бизнес-логики (model) от логики контроллера (view)?
|
|
29.10.2015, 10:52
|
Кандидат Javascript-наук
|
|
Регистрация: 16.02.2012
Сообщений: 109
|
|
set_cus_events - это пустая функция, наследники этого класса туда будут запихивать свои обработчики событий, а set_def_events - Это события которые они все будут уметь делать. Пока не дописана тут эта функция.
Вообще обработчики ставлю строками.
$(this.el).delegate('','mousedown',this.model.event_mousedown.bind(this))
event_mousedown:function(e){
// console.log('Нажата мышь');
this.set({'event_mousedown':e})
},
А потом например если откроешь кучу всплывающих окон, они будут случать этот параметр event_mousedown, через listenTo.
Вообще любую задачу можно решить процедурным способом, не используя сложных объектов. Дело вкуса любого. Мне просто нравится так, кому-то по-другому. Мой совет - попробую кучу вариантов, а потом решишь что тебе лучше, не факт что ты даже на backbone останешься ,может придется по вкусу другой продвинутый framework.
|
|
|
|