2016-10-11 2 views
0

У меня есть коллекция моделей с булевым значением interviewed, и я хочу отфильтровать их так, чтобы в моем представлении отображались либо модели с этим свойством: true или модели с этим свойством, установленным на false. В моей коллекции у меня есть следующие методы:Фильтрация коллекции не работает

var ResumeCollection = Backbone.Collection.extend({ 
    filterActive: function() { 
     var active = this.where({interviewed: false}); 
     return active; 
    }, 

    filterInterviewed: function() { 
     var interviewed = this.where({interviewed: true}); 
     return interviewed; 
    } 
}); 

и на мой взгляд, у меня есть следующие:

var ResumeList = Backbone.View.extend({ 
    events: { 
     'click #active': 'showActive', 
     'click #interviewed': 'showInterviewed' 
    }, 

    initialize: function() { 
     this.collection = new ResumeCollection(); 
    }, 

    render: function() { 
     var self = this; 
     this.$el.html($('#filter')); 
     _.each(this.collection.toArray(), function (cv) { 
      self.$el.append((new ResumeView({model: cv})).render().$el); 
     }); 
    }, 

    showActive: function() { 
     this.collection.filterActive(); 
     this.render(); 
    }, 

    showInterviewed: function() { 
     this.collection.filterInterviewed(); 
     this.render(); 
    } 
}); 

Но когда я нажимаю #active или #interviewed кнопки, то ничего не происходит и модели с требуемыми свойства не отображаются. Я уже пытался управлять этим методом reset или возвращать новый экземпляр коллекции с требуемыми моделями, но это не решение, потому что когда я успешно фильтрую исходную коллекцию, она возвращает мне новую коллекцию с моделями, которые мне нужны (например, модели где interviewed: true), и я не могу отфильтровать его больше - он возвращает только пустую коллекцию. Я просто не могу понять, как я могу отфильтровать эту коллекцию так, как мне нужно.

+0

Вам необходимо отфильтровать модели внутри коллекций и вернуть отфильтрованные модели. В вашем случае 'interviewed' является только параметром коллекции. –

+0

У меня параметр 'интервьюируемый' по умолчанию в моей модели – AlexNikolaev94

ответ

2

Вы возвращающая успешно отфильтрованную коллекцию, а затем с ними ничего не делает.

showActive: function() { 
    this.collection.filterActive();//returns a value you're not using 
    this.render(); 
}, 

showInterviewed: function() { 
    this.collection.filterInterviewed();//returns a value you're not using 
    this.render(); 
} 

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

Заимствование некоторых из кода Симо, чтобы вернуть новую коллекцию.

filterActive: function() { 
    var active = this.where({interviewed: false}); 
    return new ResumeCollection(active); 
}, 

filterInterviewed: function() { 
    var interviewed = this.where({interviewed: true}); 
    return new ResumeCollection(interviewed); 
}, 

render: function (filtered) { 
    var self = this; 
    var data = filtered ? filtered.toArray() : this.collection.toArray(); 
    this.$el.html($('#filter')); 
    _.each(data , function (cv) { 
     self.$el.append((new ResumeView({model: cv})).render().$el); 
    }); 
}, 

showActive: function() { 
    var filtered = this.collection.filterActive(); 
    this.render(filtered); 
}, 

showInterviewed: function() { 
    var filtered = this.collection.filterInterviewed(); 
    this.render(filtered); 
} 
+0

Спасибо! Он работает почти идеально и делает то, что мне нужно, кроме одной ошибки - когда представление отображается впервые, оно возвращает мне ошибку «filter.toArray не является функцией» и ничего не отображает. Но когда я нажимаю кнопки, события действуют точно так, как мне нужно, и визуализируют нужные мне модели. Любые предложения об этой ошибке? – AlexNikolaev94

+0

** ADDED ** Сейчас я ищу отладчика, и кажется, что когда представление визуализируется в первый раз, 'data' сначала получает пустой массив, а затем становится' undefined', что вызывает ошибку – AlexNikolaev94

+1

Когда представление отображается в первый раз, вы передаете какие-либо аргументы? Если нет, то тернарный оператор должен по умолчанию использовать 'this.collection.toArray()'. Если вы передадите аргумент, функция рендеринга ожидает, что это будет коллекция Backbone. –

0

Ваша проблема в том, что вы не возвращаете отфильтрованную коллекцию.

Это должно работать:

filterActive: function() { 
    var active = this.filter(function(item) { 
     return item.get('interviewed') === false; 
    }); 

    return new ResumeCollection(active); 
}, 

filterInterviewed: function() { 
    var interviewed = this.filter(function(item) { 
     return item.get('interviewed') === true; 
    }); 

    return new ResumeCollection(interviewed); 
}, 
+0

, к сожалению, это не сработало :(И вот я получаю в результате новую коллекцию - но что, если мне нужно будет фильтровать для тех, у кого есть другой параметр сейчас? Я имею в виду, что если эти функции будут успешными, в результате я получу набор моделей, где 'интервью === false'.Но тогда я не смогу фильтровать коллекции, где 'интервью === true', если я не обновляю страницу вручную – AlexNikolaev94

+0

Я не понимаю: зачем вам обновлять браузер вручную, чтобы получить коллекцию, где 'интервью == правда'? –

+0

, потому что всякий раз, когда я фильтрую начальную коллекцию, я получаю новую коллекцию с моделями, которые имеют только «опрошенные === true» или «опрошенные === false» параметры, что делает невозможным ее фильтрацию снова. Я имею в виду, например, что я успешно фильтрую исходную коллекцию и получаю новую коллекцию моделей с «интервьюированным === false». Затем, если я хочу снова фильтровать коллекцию, и если я ее фильтрую, я просто получаю пустую коллекцию. – AlexNikolaev94

0

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

Теперь при визуализации полной коллекции вы можете назвать, как делают

render(this.collection.models) // reference to list of models 

также, если вы отфильтровать коллекцию, то функция фильтра, скорее всего, будет возвращающимся подмножество моделей из коллекции. Что вы можете снова перейти к визуализации функции

this.render(this.showActive()) // showActive returns subset of models from collection 

Таким образом рендеринге функция становится модульным .. которая принимает массив и сделать затем на странице ..

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

Смежные вопросы