ermolaevalexey
@ermolaevalexey
frontend веб-разработчик

Как изменить состояние модели с помощью другой модели?

В проекте есть две основных модели: Meet(встреча) с некоторыми параметрами и Filter, фильтр, который должен отбирать встречи по разным параметрам. Группа всех существующих встреч - это коллекция (MeetCollection). Создаем коллекцию и отрисовываем ее на экране рендером в виде списка.
У модели Filter набор критериев, по которым пользователь хочет найти встречи. Пока он только один - день недели. Он выводится в виде селекта. Нужно чтобы по выбору дня недели в MeetCollection встреч отображались только модели, соответствующие выбранному дню.
(у обеих моделей есть свойство weekDay). Я создал в модели Filter метод filterByDay(), который отбирает модели по дню, и если день не соответствует выбранному, модель в коллекции уничтожается.
Но пока я вызывал его отдельно от представления - так как не могу понять как вызвать его по событию выбора опции. Прошу помощи у сообщества.

Модель Meet
//creating Meet model
	App.Models.Meet = Backbone.Model.extend({
		defaults : {
			date : "01.11.2015",
			weekDay : "Sunday",
			timeBegin : "12:00",
			timeEnd : "00:00",
			games : [],
			placeName : "PlayLoft Gaga",
			placeAddress : "Малая Морская, 15/7"
		},
	});
	//end//

Модель Filter
App.Models.Filter = Backbone.Model.extend({

		defaults : {
			weekDay : "Monday",
		},
         //Метод фильтрации
		filterByDay : function(collection) {  
          for(var i = 0; i < collection.models.length; i++ ) {
             if(collection.models[i].get('weekDay') != this.get('weekDay')){
                   collection.models[i].destroy();
              }      
          } 
          return ;
		}

	});

Вьюха одной встречи в коллекции:
App.Views.Meet = Backbone.View.extend({

		tagName : 'li',
		template : template('meetsTemplate'),
		initialize : function(){
			this.model.on('destroy', this.remove, this);
		},

		render : function() {
			var template = this.template(this.model.toJSON());
			this.$el.html(template);
			return this;
		},

		destroy: function() {
			this.model.destroy();
		},
		remove: function() {
			this.$el.remove();
		}

	});

Вьюха фильтра в коллекции фильтров
App.Views.Filter = Backbone.View.extend({
		tagName : 'option',
		className : 'day',
		template : template('chooseTemplate'),
		render : function() {
			var template = this.template(this.model.toJSON());
			this.$el.html(template);
			return this;
		},
		events : {
			'click' : 'change'
		},
		destroy: function() {
			this.model.destroy();
		},
		remove: function() {
			this.$el.remove();
		},
	});


Эта часть уже не актуальна
UPD: В ходе изысканий было обнаружено, что метод, который я написал для фильтрации, влияет не на всю коллекцию, какая-то часть остается(2, 3 или 4 элемента, зависит от размера коллекции).
Похоже, когда элемент коллекции уничтожается, изменяется и длина массива моделей, коллекция перерисовывается заново, и индексы элементов смещаются.
Получается, нужно уничтожать нулевой элемент каждый раз?


UPD2: Проблема с методом решилась рекурсией

Для полного понимания картины я выложил полный код на фиддл:

https://jsfiddle.net/wxuzbnf6/12/

Буду очень признателен, если кто-нибудь поможет мне заметить, что я не доглядел и подскажет как можно правильно вызвать метод модели Filter в модели Meet.
  • Вопрос задан
  • 434 просмотра
Пригласить эксперта
Ответы на вопрос 2
Fesor
@Fesor
Full-stack developer (Symfony, Angular)
Ну как бы так как вы и написали в заголовке - модель меняет модель. По сути только вьюшкам запрещено напрямую менять модель.

Варианта 2:

1) у модели для фильтров есть доступ к модели коллекции айтемов. По изменению она сама меняет коллекцию, заставляее ее изменить состояние под наше.

2) доменные или просто ивенты между моделями коллекций и фильтрами. Сложнее, но зато при должном подходе получается весьма гибко и удобно, а главное с низкой связанностью. А если еще и с доменными событиями то можно придумать еще массу прикольных штук, но я пока так не упарывался (хотя планирую поэксперементировать).
Ответ написан
k12th
@k12th
console.log(`You're pulling my leg, right?`);
Но пока я вызывал его отдельно от представления - так как не могу понять как вызвать его по событию выбора опции.

А в чем именно проблема? Не знаете как красиво передать одну модель в другую? Используйте Dependency Injection или хотя бы Resource Registry.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы