2013-11-09 2 views
0

У меня есть 2 текстовых поля с идентификатором source,destination. Если какое-либо значение поля изменяется, соответствующий атрибут модели будет изменен. Я сделал это, используя Backbone.Model and events object in Marionette.CompositeView. он работает нормально.Как использовать modelEvents в Marionette.js

Как только любая функция изменения атрибута соответствующей функции вызовет. Для этого я написал следующий код.it не работает, проблема заключалась в том, что даже один атрибут меняет обе функции, которые оцениваются.

модель Код:

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

проблемы:

  1. Первоначально Если я ввести любое значение в первом поле (источник), получить 2 коробки Alert ("Пуск", "конец").

  2. Первоначально Если ввести любое значение во втором поле (назначения) получать 4 коробки оповещения («Пуск», «конец», «начать», «конец»)

Я пробовал много, но я не понял, где у меня проблема

Может кто-нибудь мне помочь.

Благодаря

ответ

3

modelEvents должны быть соединены :. Скажем, событие меняющегося startPlace должно быть

'change:startPlace' 

Если вы используете пространство вы будете закончить с двумя событиями, а не один событий, специфичных для данного атрибута.

Ваш код 'change startPlace' представляет собой два события, один - «изменение», другой - «startPlace». Таким образом, вы увидите «старт», «конец», «старт», «конец»

+0

Спасибо за ваш ответ, во всех случаях первое полевое мероприятие работает нормально. Но второе полевое событие выполняется 2 раза. Из-за этого я получаю 2 окна оповещения («конец», «конец»). Как я могу это исправить. – user2873816

+0

Да, это то, что происходит с пространством. Когда изменяется атрибут, срабатывает событие «change», два слушателя слушают «change» и все увольняются. Исправление состоит в том, чтобы заменить пространство на два столбца на два события, как я уже упоминал в ответе. –

+0

Я заменяю свой код кодом следующим образом: change: startPlace и change: endPlace'. Если первое значение поля меняется, я получаю одно окно с предупреждением, так что это нормально. Если я использую второе значение поля, то у меня есть 2 окна оповещения («конец», «конец»). – user2873816

0

Мои наблюдения являются для решения (однако я предлагаювторой раствор в нижней части):

  • Связывание события сущности имеет синтаксис двоеточия. Это должен быть хэш конфигурации { "event:name": "eventHandler" }. Несколько обработчиков могут быть разделены пробелом. Вместо имени строкового обработчика может быть задана функция.

  • Вы можете использовать преимущество свойства el вида позвоночника. Вместо использования document.getElementById(this.ui.sourcePlace) вы можете использовать this.$('#source'). Этот последний ищет только в контексте el, а не в поиске всего дома. Таким образом, оценка будет быстрее.Таким образом, вы должны использовать это выражение: 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'));}); 
}); 

Для каждого образца кода я использовал этот шаблон (я использовал класс селекторы вместо идентификаторов селекторов):

<div id="mapDiv"> 
    <input type="text" class="source"> 
    <input type="text" class="destination"> 
</div> 
Смежные вопросы