javascript Backbone.js 事件绑定破坏了单选按钮功能
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7179948/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
backbone.js event binding is breaking radio buttons functionality
提问by ntheitroad
I am pretty new to Backbone.js, but I am pretty sure I am doing this right.
我对 Backbone.js 很陌生,但我很确定我做对了。
Here are my Backbone view and models:
这是我的 Backbone 视图和模型:
// USER MODEL
// 用户模型
var User = Backbone.Model.extend({
defaults: {
UserID: 0,
FirstName: "",
LastName: "",
Assignment: 0,
Selected: false
},
toggle: function (){
var value = this.get("Selected");
this.set({ Selected : !value });
}
});
// USER VIEW
// 用户视图
var UserView = Backbone.View.extend({
parentview: null, // the parent view
initialize: function () {
this.parentview = this.options.parentview
this.template = $("#user-template")
this.model.bind("change", this.render, this);
},
render: function () {
var content = this.template.tmpl(this.model.toJSON());
$(this.el).html(content);
return this;
},
events: {
"click ul li": "toggle"
},
toggle: function () {
this.model.toggle();
}
});
And here is the JQuery template that I am using for each user's view. The view is rendered inside another big view, that is the collection.
这是我用于每个用户视图的 JQuery 模板。该视图呈现在另一个大视图中,即集合。
<ul id="user-container"
{{if Selected == 1 }} class="selected" {{/if}}
>
<li class="col1" {{if Selected == 0}} style="visibility:hidden" {{/if}} >
<img src="@Content.ImageUrl("pin-icon.png", "base")" />
</li>
<li class="col2">${FirstName} ${LastName} </li>
<li class="col3-last">
<input id="radio-${$item.view}-PM-${UserID}" name="radio-${$item.view}-${UserID}" type="radio" value="1" class="button"
{{if Assignment == 1}} checked="checked" {{/if}}
/>
<label for="radio-${$item.view}-PM-${UserID}">
PM</label>
<input id="radio-${$item.view}-SV-${UserID}" name="radio-${$item.view}-${UserID}" type="radio" value="2" class="button"
{{if Assignment == 2 }} checked="checked" {{/if}}
/>
<label for="radio-${$item.view}-SV-${UserID}">
STAFF</label>
<input id="radio-${$item.view}-NA-${UserID}" name="radio-${$item.view}-${UserID}" type="radio" value="0" class="button"
{{if Assignment == 0 }} checked="checked" {{/if}}
/>
<label for="radio-${$item.view}-NA-${UserID}">
NONE</label>
</li>
</ul>
In the last li
I have three radio buttons, with dynamic id's and the same name (also dynamic). Each button has its own label.
在最后li
我有三个单选按钮,具有动态 ID 和相同的名称(也是动态的)。每个按钮都有自己的标签。
All was working fine, the radio buttons were selecting and doing their job fine, until I added this line "click ul": "toggle"
in the view's events.
一切正常,单选按钮正在选择并正常工作,直到我"click ul": "toggle"
在视图的事件中添加了这一行。
The event works, when I click each user's row in the view, the model is updated and the user is selected / deselected.
该事件有效,当我单击视图中每个用户的行时,模型会更新并选择/取消选择用户。
Only thing is, that with this line, the radio buttons just don't work. The values are set, but nothing happens when I try to change the value (click on another radio button).
唯一的问题是,有了这条线,单选按钮就不起作用了。值已设置,但当我尝试更改值时没有任何反应(单击另一个单选按钮)。
No error is generated in browser console, which is weird...
浏览器控制台中没有生成错误,这很奇怪......
CORRECTION: When I click on a radio button, the click event from the backbone view is triggered, the selection is being done, but the button stays unchecked. It seems that backbone takes over, but all I want is to trigger just when I click on the
ul
portion, not on other elements inside, like buttons, etc.However, when I click on the labels for the buttons, nothing happens. No backbone event is triggered, and no button is selected.
更正:当我点击一个单选按钮时,主干视图中的点击事件被触发,选择正在完成,但按钮保持未选中状态。似乎主干接管了,但我想要的只是在我点击该
ul
部分时触发,而不是点击内部的其他元素,如按钮等。但是,当我单击按钮的标签时,没有任何反应。没有触发主干事件,也没有选择按钮。
Anyone has any idea why this might happen?
任何人都知道为什么会发生这种情况?
回答by Johnny Oshika
The checkbox is not changed in the UI because whenever a checkbox is clicked, the click event propagates to the "li" element and toggle callback is called. When the toggle callback is called, you're re-rendering your whole view, and since the "Assignment" attribute of your User model isn't being changed, you're re-rendering the view with the same "checked" state as before.
UI 中的复选框不会更改,因为无论何时单击复选框,单击事件都会传播到“li”元素并调用切换回调。当调用切换回调时,您正在重新渲染整个视图,并且由于您的用户模型的“分配”属性没有被更改,因此您正在重新渲染具有相同“已检查”状态的视图前。
You can solve this problem by preventing the propagation of the click event when it's initialized by the radio button. For example add the following radio button click handler to your view:
您可以通过在单选按钮初始化单击事件时阻止单击事件的传播来解决此问题。例如,将以下单选按钮单击处理程序添加到您的视图中:
events: {
"click input[type=radio]": "onRadioClick",
"click ul li": "toggle"
},
onRadioClick: function (e) {
e.stopPropagation();
this.model.set({ Assignment: $(e.currentTarget).val() }, {silent:true}); // {silent: true} is optional. I'm only doing this to prevent an unnecessary re-rendering of the view
},
This will intercept the click event whenever the radio button is clicked and prevent your toggle callback from being called. Notice that I'm also updating the Assignment attribute on your User model so that when your view re-renders next time, your checked state will be properly set.
每当单击单选按钮时,这都会拦截单击事件,并防止调用切换回调。请注意,我还更新了您的 User 模型上的 Assignment 属性,以便下次重新呈现您的视图时,您的选中状态将被正确设置。