我有2个id为source,destination
的文本字段。如果任何字段值发生更改,则相应的模型属性将更改。我使用Backbone.Model and events object in Marionette.CompositeView
做了这个。它工作正常。
一旦任何模型属性改变相应的函数将调用。为此我写了以下代码。它不起作用问题是即使一个属性改变了两个函数都在评估。
型号代码:
var mapModel = Backbone.Model.extend({
defaults: {
startPlace: "",
endPlace: ""
}
});
Marionette.CompositeView代码:
var mapView = Marionette.CompositeView.extend({
events: {
"blur #source": "sAttributeSetting",
"blur #destination": "dAttributeSetting"
},
dAttributeSetting: function() {
this.model.set({"endPlace": document.getElementById(this.ui.destinationPlace).value});
},
sAttributeSetting: function() {
this.model.set({"startPlace": document.getElementById(this.ui.sourcePlace).value});
},
modelEvents: {
"change startPlace": "startMarkerDisplay",
"change endPlace": "endingMarkerDisplay"
},
startMarkerDisplay: function() {
alert("start");
},
endingMarkerDisplay: function() {
alert("end");
}
});
html代码:
<input type="text" id="source">
<input type="text" id="destination">
为模型和视图创建实例
mapModelObj = new mapModel();
var mapViewObj = new mapView({el:$('#mapDiv'), model:mapModelObj});
问题:
最初如果我在第一个字段(来源)中输入任意值,获得2个警告框(“开始”,“结束”)。
最初如果您在第二个字段(目标)中输入任意值,则会收到4个警告框(“开始”,“结束”,“开始”,“结束”)
我尝试了很多,但我不明白我在哪里遇到问题
任何人都可以帮助我。
由于
答案 0 :(得分:3)
modelEvents
应通过:
连接。比如说,更改startPlace的事件应该是
'change:startPlace'
如果您使用空格,您将以两个事件结束,而不是一个特定于此属性的事件。
您的代码'change startPlace'
代表两个事件,一个是“更改”,另一个是“startPlace”。所以你会看到“开始”,“结束”,“开始”,“结束”
答案 1 :(得分:0)
我的观察结果如下(但我建议 第二解决方案在底部):
实体事件的绑定具有冒号语法。它应该是{ "event:name": "eventHandler" }
配置的哈希值。多个处理程序可以用空格分隔。可以提供函数而不是字符串处理程序名称。
您可以利用骨干视图的el
属性。
您可以使用document.getElementById(this.ui.sourcePlace)
,而不是使用this.$('#source')
。这最新搜索仅在el
的上下文中搜索,而不是搜索整个dom。这样评估会更快......这样你应该使用这个表达式:this.$('.destination').val()
请检查我的问题:http://jsfiddle.net/orbanbotond/VEcK6/
代码如下:
var mapModel = Backbone.Model.extend({
defaults: {
startPlace: "",
endPlace: ""
}
});
var mapView = Marionette.CompositeView.extend({
events: {
"blur .source": "sAttributeSetting",
"blur .destination": "dAttributeSetting"
},
dAttributeSetting: function(){
console.log('end blured');
console.log('input value:' + this.$('.destination').val());
this.model.set({
"endPlace": this.$('.destination').val()
});
console.log('endplace set to: ' + this.model.get('endPlace'));
},
sAttributeSetting: function() {
console.log('start blured');
console.log('input value:' + this.$('.source').val());
this.model.set({
"startPlace": this.$('.source').val()
});
console.log('startPlace set to: ' + this.model.get('startPlace'));
},
modelEvents: {
"change:startPlace": "startMarkerDisplay",
"change:endPlace": "endingMarkerDisplay"
},
startMarkerDisplay: function () {
alert("start");
},
endingMarkerDisplay: function () {
alert("end");
}
});
$(document).ready(function(){
var mapModelObj = new mapModel();
var mapViewObj = new mapView({
el: $('#mapDiv'),
model: mapModelObj
});
});
我建议的第二个解决方案:
使用stickit库完成您所做的一切。您只需要定义dom选择器和观察到的模型属性之间的映射。
以下是jsfiddle:http://jsfiddle.net/orbanbotond/fm64P/
以下是代码:
var mapModel = Backbone.Model.extend({
defaults: {
startPlace: "initialStartPlace",
endPlace: "initialEndplace"
},
});
var mapView = Marionette.CompositeView.extend({
template: "#mapDiv",
events: {
"blur .source": "sAttributeSetting",
"blur .destination": "dAttributeSetting"
},
bindings: {
'.source': {
observe: 'startPlace'
},
'.destination': {
observe: 'endPlace'
}
},
onRender: function() {
this.stickit();
console.debug("Sticked to it already");
},
});
$(document).ready(function(){
var mapModelObj = new mapModel();
var mapViewObj = new mapView({
el: $('#mapDiv'),
model: mapModelObj
});
mapViewObj.render();
mapModelObj.bind('change:startPlace', function(obj){alert("New value: " + obj.get('startPlace'));});
mapModelObj.bind('change:endPlace', function(){alert("New value: " + obj.get('endPlace'));});
});
对于我使用此模板的每个代码示例(我使用了类选择器而不是id选择器):
<div id="mapDiv">
<input type="text" class="source">
<input type="text" class="destination">
</div>