backbone.js 如何在Marionette.js中使用modelEvents

ccgok5k5  于 2022-11-10  发布在  其他
关注(0)|答案(2)|浏览(219)

我有两个id为source,destination的文本字段。如果任何字段值改变,相应的模型属性也会改变。我用Backbone.Model and events object in Marionette.CompositeView做了这个。它工作得很好。
一旦任何模型属性改变,相应的函数将被调用。为此我写了下面的代码。它不工作的问题是,即使一个属性改变两个函数都在评估。
型号代码:

var mapModel = Backbone.Model.extend({
  defaults: {
    startPlace: "",
    endPlace: ""
  }
});

组合视图代码:

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});

问题:
1.最初,如果我输入任何值在第一个字段(源)得到2个警报框(“开始”,“结束”)。
1.最初,如果您在第二个字段(目的地)输入任何值,将获得4个警报框(“开始”,“结束”,“开始”,“结束”)
我试了很多次,但我不明白问题出在哪里
谁能帮帮我。
谢谢

c7rzv4ha

c7rzv4ha1#

modelEvents应该由:连接。例如,更改startPlace的事件应该是

'change:startPlace'

如果使用空格,则将以两个事件结束,而不是一个特定于此属性的事件。
你的代码'change startPlace'代表两个事件,一个是“change”,另一个是“startPlace”。所以你会看到“start”,“end”,“start”,“end”

9q78igpj

9q78igpj2#

对于您的解决方案,我的观察结果如下(但是,我建议在底部提供第二个解决方案):

  • 实体事件的绑定具有冒号语法。它应该是{ "event:name": "eventHandler" }配置的哈希。可以用空格分隔多个处理程序。可以提供函数而不是字符串处理程序名称。
  • 你可以利用 Backbone.js 视图的el属性。你可以使用this.$('#source')来代替document.getElementById(this.ui.sourcePlace)。这个最新的搜索只在el的上下文中进行,而不是搜索整个dom。这样求值会快很多......这样你应该使用下面的表达式:this.$('.destination').val()

请检查我的jsfiddle关于您的问题: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选择器和观察到的模型属性之间的Map。
下面是它的jsfidle: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>

相关问题