我创建了一个搜索栏,但是当从用户那里收集数据时,它会再次显示默认数据,而不是用户新的搜索条件。
我正在重置集合并在用户搜索时为其提供一个新的 URL,但它似乎没有正确更新,而且我无法找出我的问题所在。
(function(){
'use strict';
var red = red || {};
//model////////////////////////////////////////////////
red.RedditModel = Backbone.Model.extend({
defaults: {
urlTarget: $('#textBox').val(),
urlStart: 'https://www.reddit.com/r/',
urlEnd: '.json'
},
initialize: function() {
this.on('change:urlTarget', function() {
console.log('The Url Target has changed to ' + this.get("urlTarget"));
});
this.on('change:concatURL', function() {
console.log('The model Url has changed to ' + this.get("concatURL"));
});
this.on('change:url', function() {
console.log('The collection url has changed to: ' + this.get('url'));
});
}
});
var redditModel = new red.RedditModel();
var fullURL = new red.RedditModel({
concatURL: redditModel.attributes.urlStart + redditModel.attributes.urlTarget + redditModel.attributes.urlEnd
});
var listElmement,
$list = $('.list');
//collections//////////////////////////////////////////
red.redditCollection = Backbone.Collection.extend({
model: red.RedditModel,
url: fullURL.attributes.concatURL,
parse: function(response) {
var redditData = response.data.children;
return redditData;
}
});
//view////////////////////////////////////
red.RedditView = Backbone.View.extend({
model: fullURL,
collection: redditCollection,
el: '.searchBar',
events: {
'click .searchButton': function(e) {
this.updateModel(e);
this.updateCollection(e);
},
'change #textBox': 'initialize'
},
updateModel: function() {
this.$urlTarget = $('#textBox').val()
this.model.set('urlTarget', this.$urlTarget);
this.model.set('concatURL', redditModel.attributes.urlStart + this.$urlTarget + redditModel.attributes.urlEnd);
},
updateCollection: function() {
this.collection.reset();
this.$urlTarget = $('#textBox').val();
var newUrl = redditModel.attributes.urlStart + this.$urlTarget + redditModel.attributes.urlEnd;
this.collection.add({ urlTarget: this.$urlTarget });
this.collection.add({ url: newUrl });
console.log(newUrl);
},
tagName: 'li',
className: 'listItems',
initialize: function() {
$list.html('');
this.collection.fetch({
success: function(redditData) {
redditData.each(function(redditData) {
redditData = redditData.attributes.data.title
listElmement = $('<li></li>').text(redditData);
$list.append(listElmement);
})
}
});
},
render: function() {
}
});
var redditCollection = new red.redditCollection({
redditModel,
fullURL
});
var myRedditView = new red.RedditView({
model: redditModel,
collection: redditCollection
});
$('.page').html(myRedditView.render());;
})();
最佳答案
在模型中解析,并将其用于预期目的。无需在模型中存储 reddit url 和其他搜索相关信息。
red.RedditModel = Backbone.Model.extend({
parse: function(data) {
return data.data;
},
})
因为您已经在这里处理了 reddit url。不要害怕在 Backbone 扩展对象( View 、模型、集合等)中为自己创建一些实用函数和 getter/setter。
red.RedditCollection = Backbone.Collection.extend({
url: function() {
return 'https://www.reddit.com/r/' + this.target + this.extension;
},
initialize: function(models, options) {
this.extension = '.json'; // default extension
},
setExtension: function(ext) {
this.extension = ext;
},
setTarget: function(target) {
this.target = target;
},
parse: function(response) {
return response.data.children;
}
});
不要害怕有很多 View ,应该使用 Backbone View 来包装小的组件逻辑。
所以这是项目:
red.RedditItem = Backbone.View.extend({
tagName: 'li',
className: 'listItems',
render: function() {
this.$el.text(this.model.get('title'));
return this;
}
});
列表使用的是:
red.RedditList = Backbone.View.extend({
tagName: 'ul',
initialize: function() {
this.listenTo(this.collection, 'sync', this.render);
},
render: function() {
this.$el.empty();
this.collection.each(this.renderItem, this);
return this;
},
renderItem: function(model) {
var view = new red.RedditItem({ model: model });
this.$el.append(view.render().el);
}
});
而列表只是我们 Root View 的一个子组件( subview )。
red.RedditView = Backbone.View.extend({
el: '.searchBar',
events: {
'click .searchButton': 'onSearchClick',
},
initialize: function() {
// cache the jQuery element for the textbox
this.$target = $('#textBox');
this.collection = new red.RedditCollection();
this.list = new red.RedditList({
collection: this.collection,
// assuming '.list' is within '.searchBar', and it should
el: this.$('.list'),
});
},
render: function() {
this.list.render();
return this;
},
onSearchClick: function(e) {
this.collection.setTarget(this.$target.val());
console.log(this.collection.url());
this.collection.fetch({ reset: true });
},
});
那么,您只需具备以下条件即可使用它:
var myRedditView = new red.RedditView();
myRedditView.render();
请注意几乎不使用全局 jQuery 选择器。如果您使用 Backbone 并且在任何地方使用 $('#my-element')
,那么您就违背了 Backbone 的目的,该目的部分是应用 MVC 概念在 jQuery 之上。
贴出的代码的一些注释
花点时间了解发生了什么。您的问题中有几行代码没有执行任何操作,或者根本不起作用。
虽然它已在您的答案中删除,但以下内容没有意义,因为集合构造函数是 Backbone.Collection([models], [options])
并且您在此处所拥有的转化为传递options
对象(使用 ES6 shorthand property names { a, b, c}
)到 models
参数。
var redditCollection = new red.redditCollection({
redditModel,
fullURL
});
这一行什么都不做,因为 .render()
什么都不做,也不返回任何东西。
$('.page').html(myRedditView.render());
在这里,您使用 jQuery 手动创建一个新元素,而您有 Backbone 为您做这件事。
$('<li></li>').text(redditData);
不要直接使用 attributes
,总是使用 .get('attributeKey')
除非你有充分的理由不这样做。
redditModel.attributes.urlStart
尽可能使用局部变量。此处的 listElement
var 是在“app”级别定义的,不需要它。
listElmement = $('<li></li>').text(redditData);
$list.append(listElmement);
主干集合会在成功时自动填充模型的新实例。您不需要在成功回调中重新解析它(除了与 redditData
的歧义之外)。
this.collection.fetch({
success: function(redditData) {
redditData.each(function(redditData) {
redditData = redditData.attributes.data.title;
我并不是有意无礼,我花时间写下这么长的答案是为了帮助您和任何 future 的读者。
关于javascript - 在 Backbonejs 中更新集合和 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40219846/