Javascript-форум (https://javascript.ru/forum/)
-   Backbone.js (https://javascript.ru/forum/backbone/)
-   -   Backbone порядок наступления событий (https://javascript.ru/forum/backbone/58991-backbone-poryadok-nastupleniya-sobytijj.html)

armidoll 21.10.2015 13:45

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 <-- Выводит в последнюю очередь


Т.е. более конкретно определенное событие при прочих равных обрабатывается ранее?
Это особенность фреймворка или чего-то другого?
Или тут имеет место некий аналог "всплытия" события для модели?

vuler 25.10.2015 21:24

Лучше пример приведи, где это может вызвать проблему. Вообще бэкбоне достаточно гибкий. Если грамотно научить модели слушать события и параметры друг у друга, конфликтов можно избежать. Я в своем коде коде создаю обычно материнский класс, который регистрирует все события - нажатия мышей и прочее, а другие классы его прослушивают и получают команды, когда можно что-то сделать, когда нет.

рони 25.10.2015 22:22

:write: мысли вслух: поставили функции на два события - сначала сработали функции от события 'change:name' потом выше от просто 'change'

armidoll 26.10.2015 10:28

Вопрос был: Почему так?
А не: У меня проблема с этим.../ Как сделать что-то...
Думал, может кто на форуме владеет достаточными знаниями по сабжу, чтобы просветить.

Цитата:

Сообщение от vuler (Сообщение 393076)
Я в своем коде коде создаю обычно материнский класс, который регистрирует все события - нажатия мышей и прочее, а другие классы его прослушивают и получают команды, когда можно что-то сделать, когда нет.

И что играет роль 'материнского класса"?
view, collection или model (подозреваю, что не два последних)?

И пример кода можно глянуть для предлагаемого паттерна?

vuler 28.10.2015 23:00

Каждый пишет код как ему нравится. Я раньше разделял 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();
	})
})

armidoll 29.10.2015 01:42

Ok. Спасибо за пример.

Я не скрываю, что я еще очень юный javascript и Backbone падаван, но в такой архитектуре приложения, когда обработка событий генерируемых пользователем находится в model (тут ведь, например, обрабатывается клик мыши на какую-нибудь кнопку "добавить"?)
set_cus_events:function(){//Установка событий
    }

а не во view, нет противоречия самой концепции Backbone как решения для отделения бизнес-логики (model) от логики контроллера (view)?

vuler 29.10.2015 10:52

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.


Часовой пояс GMT +3, время: 05:02.