0

我有 2 个带有 id 的文本字段source,destination。如果任何字段值更改,则相应的模型属性将更改。我用Backbone.Model and events object in Marionette.CompositeView. 它工作正常。

一旦任何模型属性发生变化,相应的函数就会调用。为此,我编写了以下代码。即使两个函数都在评估一个属性更改,它也不起作用。

型号代码:

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

Marionette.Composite查看代码:

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 个警报框(“开始”,“结束”)。

  2. 最初,如果您在第二个字段(目的地)中输入任何值,则会得到 4 个警报框(“开始”、“结束”、“开始”、“结束”)

我尝试了很多,但我不明白问题出在哪里

谁能帮我。

谢谢

4

2 回答 2

3

modelEvents应由 连接:。说,改变 startPlace 的事件应该是

'change:startPlace'

如果您使用空格,您将以两个事件结束,而不是一个特定于该属性的事件。

你的代码'change startPlace'代表两个事件,一个是'change',另一个是'startPlace'。所以你会看到 "start","end","start","end"

于 2013-11-09T07:32:10.797 回答
0

我对您的解决方案的观察如下(但是我在底部提出第二种解决方案):

  • 实体事件的绑定有冒号语法。它应该是{ "event:name": "eventHandler" }配置的哈希。多个处理程序可以用空格分隔。可以提供函数而不是字符串处理程序名称。

  • 您可以利用el主干视图的属性。document.getElementById(this.ui.sourcePlace)您可以使用 ,而不是使用this.$('#source')。这个最新的搜索只在上下文中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 选择器和被观察模型属性之间的映射。

这是它的 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>
于 2013-11-09T17:29:09.197 回答