2015-07-29 1 views
0

Я использую CompositeView для отображения тега select, а опции отображаются с помощью коллекции CompositeView.Получение выбранного параметра при использовании Marionette CompositeView с тегом select

OptionView = Marionette.ItemView.extend({ 
    template: ... 
    tagName: "option", 
    } 
}); 

SelectView = Marionette.CompositeView.extend({ 
    template: ...   
    childView: OptionView, 
    childViewContainer: "select",  

    triggers: { 
     "change @ui.select": "do:something" 
    }, 

    ui:{ 
     select: "[ui-select]" 
    }, 
}); 

Странная вещь, что, когда я пытаюсь получить выбранный вариант из LayoutView, который держит SelectView, я получаю противоречивое поведение:

EditActivities.LayoutView = Marionette.LayoutView.extend({ 
    template: ... 
    regions: ... 

    onChildviewDoSomething: function(view){ 
     console.log(view.ui.select.val()); 
    } 
}) 

При изменении значения избранного тега в браузере, иногда то, что регистрируется на консоли, является внутренним HTML тега параметра, и иногда оно регистрирует значение. Вот как выглядит мой шаблон OptionView:

<option value="<%=id%>"><%= name %></option> 

Я немного в тупике по непоследовательному поведению. Идеи?

+0

Это звучит странно, можно привести пример на plnkr, jsfiddle или подобного, воспроизводящий его? Я не могу сразу увидеть что-то не так с кодом, который вы опубликовали. – ivarni

ответ

1

Я понял. Проблема была в OptionView, я указывал, что tagName является «опцией». В шаблоне у меня также был тег опции, который по существу создал набор вложенных тегов параметров. Именно это и вызывало непредсказуемое поведение.

Я изменил его таким образом мой шаблон теперь просто:

<%= name %> 

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

initialize : function (options) { 
    this.$el.attr("value",this.model.attributes.id); 
} 

но я определенно открыт к тому, если есть лучший способ сделать это ...

1

Чтобы включить значение атрибут опции вместе с innerHTML, без необходимости прибегать к модификации вещей в Initialize, вы можете использовать атрибуты магистральных хеш, как это:

SelectView = Marionette.CompositeView.extend({ 
    tagName: 'option', 
    template: _.template('<%= name %>'), 
    attributes: function() { 
    return { 
     'value': this.model.id 
    }; 
    } 
}); 
0

Как уже упоминалась гигантская акула, хэш-атрибутов может быть использован для определения атрибутов опции элементы. Элемент Item может быть использован для элемента опции.

var OptionView = Marionette.ItemView.extend({ 
    tagName: 'option', 
    attributes: function() { 
     return { 
      'value': this.model.get('id') 
     } 
    }, 
    template: _.template('<%= name %>') 
}); 

Вид коллекции, который использует вид элемента, может использоваться для тега select.

var SelectOptionsView = Marionette.CollectionView.extend({ 
    childView: OptionView 
}); 

Представление коллекции может быть оказан внутри области в макете, где события на выбор тега также может быть прослушаны. Fiddle для примера: http://jsfiddle.net/95g1ojwk/3/

var pills = new Backbone.Collection([{ 
    id: '', 
    name: 'Choose' 
}, { 
    id: 'illusion', 
    name: 'Blue' 
}, { 
    id: 'reality', 
    name: 'Red' 
}]); 

var OptionView = Marionette.ItemView.extend({ 
    tagName: 'option', 
    attributes: function() { 
     return { 
      'value': this.model.get('id') 
     } 
    }, 
    template: _.template('<%= name %>') 
}); 

var SelectOptionsView = Marionette.CollectionView.extend({ 
    childView: OptionView 
}); 

var MyLayoutView = Mn.LayoutView.extend({ 
    ui: { 
     destiny: "#destiny", 
     choice: '#choice' 
    }, 
    regions: { 
     "options": "#options-region", 
    }, 
    events: { 
     'change @ui.choice': 'chosenDestiny' 
    }, 
    onRender: function() { 
     this.showChildView('options', new SelectOptionsView({ 
      collection: pills, 
      el: this.ui.choice 
     })); 
    }, 
    chosenDestiny: function (event) { 
     if($(event.target).val()==='reality'){ 
      this.ui.destiny.text('Nothing but Truth!'); 
     } else if($(event.target).val()==='illusion'){ 
      this.ui.destiny.text('The Story Ends!'); 
     } else { 
      this.ui.destiny.text('This is your last chance!'); 
     } 
    } 
}); 

new MyLayoutView({ 
    el: '#app', 
    template: '#layout-template' 
}).render(); 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
<script src="http://underscorejs.org/underscore.js"></script> 
<script src="http://backbonejs.org/backbone.js"></script> 
<script src="http://marionettejs.com/downloads/backbone.marionette.js"></script> 
<script type="text/template" id="layout-template"> 
    <div id="options-region"> 
     <select id="choice"></select> 
    </div > 
    <label id = "destiny" > </label> 
</script> 
<script type="text/template" id="image-template"> 
    <div class = "sizer" > <img src = "http://placehold.it/<%= width %>x<%= height %>" /> </div> 
</script> 
<div id="app"></div>