在下面的代码中,我有一个从另一个视图扩展的视图(但不继承任何功能,只渲染模板)和我想要实现的模型。我的观点是一个类似按钮,我需要在每次加载页面时从服务器检索类似按钮的状态。我不知道如何使用该模型。我是否需要在模型中从服务器检索状态时进行Ajax调用,或者该调用是否属于视图?
这是我的代码:
var likeButton = Backbone.Model.extend ({
initialize: function () {
this.isLiked = /* need something here! Ajax call to get state of button from server? */
}
});
var LikeButtonView = BaseButtonView.extend({ // extends form a previews view which simply extends from backbone and render's the template
template: _.template($('#like-button').html()),
sPaper: null,
sPolyFill: null,
sPolyEmpty: null,
isLiked: false,
events: {
"click .icon": "like",
},
model: new likeButton (),
initialize: function (options) {
BaseButtonView.prototype.initialize.apply(this, [options]); // inherit from BaseButtonView
this.likeButn = $("button.icon", this.$el);
this.svgNode = this.likeButn.find("svg").get(0); // find the svg in the likeButn and get its first object
this.sPaper = Snap(this.svgNode); // pass in the svg object into Snap.js
this.sPolyFill = this.sPaper.select('.symbol-solid');
this.sPolyEmpty = this.sPaper.select('.symbol-empty');
if (this.model.isLiked) {
this.likeButn.addClass("liked");
} else if (!this.model.isLiked) {
this.likeButn.addClass("unliked");
}
},
like: function() {
this._update();
},
_update: function () {
if ( !this.isLiked ) { // if isLiked is false, remove class, add class and set isLiked to true, then animate svg to liked position
this._like();
} else if ( this.isLiked ) { // is isLiked is false, remove class, add class, set isLiked to false, then animate svg to unliked position
this._unlike();
}
},
_like: function() {
this.likeButn.removeClass("unliked");
this.likeButn.addClass("liked");
this.isLiked = true;
this.sPolyFill.animate({ transform: 't9,0' }, 300, mina.easeinout);
this.sPolyEmpty.animate({ transform: 't-9,0' }, 300, mina.easeinout);
},
_unlike: function() {
this.likeButn.removeClass("liked");
this.likeButn.addClass("unliked");
this.isLiked = false;
this.sPolyFill.animate({ transform: 't0,0'}, 300, mina.easeinout);
this.sPolyEmpty.animate({ transform: 't0,0' }, 300, mina.easeinout);
}
});
答案 0 :(得分:1)
有三种方法可以实现'喜欢'按钮对页面当前状态的了解:从HTML传递的隐藏字段,对服务器的Ajax调用,或者生成javascript服务器端,类似模型的状态已经激活。
让我们从基础开始。你的代码有点混乱。 模型包含应用程序的状态,视图只不过是一种显示状态的方式,在状态更改以更新节目时接收消息,以及向模型发送消息以更改状态。模型和视图通过Backbone.Events进行通信,视图和DOM通过jQuery.Events进行通信。你必须学会将这两者分开。
在这里,我已经转过你的"喜欢"模型化为实际模型,以便Backbone.Event中心可以看到您所做的更改。
var likeButton = Backbone.Model.extend ({
defaults: {
'liked': false
}
});
现在在您的视图中,初始渲染将从模型中获取get的状态。当DOM事件(在'事件'对象中描述)发生时,您的工作就是将其转换为模型的状态更改,因此我的" toggleLike"只更改模型,而不是视图。但是,当模型发生变化时(显式地,当模型的"喜欢"字段发生变化时),视图将自动更新。
这是什么让Backbone如此酷。视图自动反映模型现实的方式。您只需要使模型正确,视图就可以工作。您可以协调视图在初始化代码中反映模型的方式,它可以很小并且很容易推断出您所关心的模型中的事件。
var LikeButtonView = BaseButtonView.extend({
template: _.template($('#like-button').html()),
events: {
"click .icon": "toggleLike",
},
initialize: function (options) {
BaseButtonView.prototype.initialize.call(this, options); // inherit from BaseButtonView
// A shortcut that does the same thing.
this.likeButn = this.$("button.icon");
this.model.on('change:liked', this._updateView, this);
},
render: function() {
BaseButtonView.prototype.render.call(this);
// Don't mess with the HTML until after it's rendered.
this.likeButn.addClass(this.model.isLiked ? "liked", "unliked");
},
toggleLike: function() {
this.model.set('liked', !this.model.get('liked'));
},
_updateView: function () {
if (this.model.get('liked')) {
this._showLikedState();
} else {
this._showUnlikedState();
}
}
});
如上所述,模型的初始化如何由您决定。您可以在模型的选项上设置一个URL,并在页面的启动代码中告诉它" fetch",在这种情况下,它会从某个REST端点获取状态在你的服务器上。或者您可以将其设置为默认值' false'。或者您可以在隐藏的HTML(隐藏的div或其他东西)中设置它,然后使用您的页面启动代码来找到它:
new LikeButtonView({model: new LikeButton({}, {url: "/where/page/state/is"}));
或
new LikeButtonView({model: new LikeButton({liked: $('#hiddendiv').data('liked')}, {}));
如果您要保存喜欢的状态,我建议您使用该网址。然后你就有了保存数据的地方。