选择中的 OptionGroup 与stickit 绑定

Posted

技术标签:

【中文标题】选择中的 OptionGroup 与stickit 绑定【英文标题】:OptionGroup in select binded with stickit 【发布时间】:2015-04-01 14:22:15 【问题描述】:

我在客户端使用 Backbone.stickit、Backbone.marionette 和 Backbone 作为版本页面。

我的模型的一个字段是从下拉列表 (

/* Models */
// Language/Models.js
Language = Backbone.Model.extend();
LanguageCollection = Backbone.Collection.extend(
    model: Language
);
// Book/Models.js
Book = Backbone.Model.extend();

/* Views */
// Book/Views.js
BookAttributesView = Marionette.ItemView.extend(
    el: "#BookAttributesBox",
    template: "#BookAttributesTemplate",
    bindings:
    
        "#Title": "Title",
        "#AuthorName": "AuthorName",
        "#LanguageCode": 
            observe: "LanguageCode",
            selectOptions: 
                collection: new LanguageCollection([ Name: "English", Code: "en", Name: "German", Code: "de" ]),
                labelPath: "Name",
                valuePath: "Code"
            
        
    ,
    onRender: function () 
        this.stickit();
    
);

/* Render view */
var book = new Book( Title: "Dune", AuthorName: "Frank Herbert", LanguageCode: "en" );
new BookAttributesView( model: book ).render();
body 
    padding: 10px;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<script src="http://underscorejs.org/underscore-min.js"></script>
<script src="http://backbonejs.org/backbone-min.js"></script>
<script src="http://marionettejs.com/downloads/backbone.marionette.min.js"></script>
<script src="https://rawgithub.com/NYTimes/backbone.stickit/master/backbone.stickit.js"></script>

<!-- Views/Books/Templates/BookAttributes.cshtml -->
<script type="text/template" id="BookAttributesTemplate">
<div class="form-group">
    <label for="Title">Title</label>
    <input id="Title" type="text" class="form-control" placeholder="Title"">
</div>
<div class="form-group">
    <label for="AuthorName">Author</label>
    <input id="AuthorName" type="text" class="form-control" placeholder="Author">
</div>
<div class="form-group">
    <label for="LanguageCode">Language</label>
    <select id="LanguageCode" class="form-control">
    </select>
</div>
</script>

<!-- Views/Books/Edit.cshtml -->
<h1>Book edition</h1>
<h2>Attributes</h2>
<div id="BookAttributesBox"></div>

【问题讨论】:

【参考方案1】:

我在backbone.stickit documentation 发现我们可以覆盖更新方法。

在我的选择绑定中,我添加了以下代码:

update: function($el, val, model, options) 
LanguageChannel.data.languages.each(function(language)
    // Find parent.
    var parent = $el.find("#LanguageReadable");
    if (language.get("isEditable"))
        parent = $el.find("#LanguageEditable");
    

    // Select correct value.
    var selected = "";
    if (language.get("Code") == val)
        selected = ' selected="selected"';
    

    // Add option to optgroup.
    parent.append("<option" + selected + ">" + language.get("Name") + "</option>");
);

这是我的整个解决方案:

/* Models */
// Language/Models.js
Language = Backbone.Model.extend();
LanguageCollection = Backbone.Collection.extend(
    model: Language
);
// Book/Models.js
Book = Backbone.Model.extend();

languages = new LanguageCollection([
                  Name: "English", Code: "en", isEditable:true,
                  Name: "French", Code: "fr", isEditable:false,
                  Name: "German", Code: "de", isEditable:true,
                  Name: "Spanish", Code: "es", isEditable:false
            ]);

/* Views */
// Book/Views.js
BookAttributesView = Marionette.ItemView.extend(
    el: "#BookAttributesBox",
    template: "#BookAttributesTemplate",
    bindings:
    
        "#Title": "Title",
        "#AuthorName": "AuthorName",
        "#LanguageCode": 
            observe: "LanguageCode",
            selectOptions: 
                collection: languages,
                labelPath: "Name",
                valuePath: "Code"
            ,
            update: function($el, val, model, options) 
                languages.each(function(language)
                    // Find parent.
                    var parent = $el.find("#LanguageReadable");
                    if (language.get("isEditable"))
                        parent = $el.find("#LanguageEditable");
                    
                    
                    // Select correct value.
                    var selected = "";
                    if (language.get("Code") == val)
                        selected = ' selected="selected"';
                    
                    
                    // Add option to optgroup.
                    parent.append("<option" + selected + ">" + language.get("Name") + "</option>");
                );
            
        
    ,
    onRender: function () 
        this.stickit();
    
);

/* Render view */
var book = new Book( Title: "Dune", AuthorName: "Frank Herbert", LanguageCode: "de" );
new BookAttributesView( model: book ).render();
body 
    padding: 10px;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<script src="http://underscorejs.org/underscore-min.js"></script>
<script src="http://backbonejs.org/backbone-min.js"></script>
<script src="http://marionettejs.com/downloads/backbone.marionette.min.js"></script>
<script src="https://rawgithub.com/NYTimes/backbone.stickit/master/backbone.stickit.js"></script>

<!-- Views/Books/Templates/BookAttributes.cshtml -->
<script type="text/template" id="BookAttributesTemplate">
<div class="form-group">
    <label for="Title">Title</label>
    <input id="Title" type="text" class="form-control" placeholder="Title"">
</div>
<div class="form-group">
    <label for="AuthorName">Author</label>
    <input id="AuthorName" type="text" class="form-control" placeholder="Author">
</div>
<div class="form-group">
    <label for="LanguageCode">Language</label>
    <select id="LanguageCode" class="form-control">
        <optgroup id="LanguageEditable" label="Editable langauges">
        <optgroup id="LanguageReadable" label="Readable languages">
    </select>
</div>
</script>

<!-- Views/Books/Edit.cshtml -->
<h1>Book edition</h1>
<h2>Attributes</h2>
<div id="BookAttributesBox"></div>

【讨论】:

【参考方案2】:

我在源代码中发现了这一点;

https://github.com/NYTimes/backbone.stickit/blob/master/backbone.stickit.js#L650-658

// To define a select with optgroups, format selectOptions.collection as an object
// with an 'opt_labels' property, as in the following:
//
//     
//       'opt_labels': ['Looney Tunes', 'Three Stooges'],
//       'Looney Tunes': [id: 1, name: 'Bugs Bunny', id: 2, name: 'Donald Duck'],
//       'Three Stooges': [id: 3, name : 'moe', id: 4, name : 'larry', id: 5, name : 'curly']
//     
//

【讨论】:

以上是关于选择中的 OptionGroup 与stickit 绑定的主要内容,如果未能解决你的问题,请参考以下文章

如何修复Backbone.stickit中的'this.stickit()不是函数'错误

Backbone Stickit 输入值从外部改变

与 require.js 和 backbone.stickit 一起使用时出现奇怪的 Backbone.Validation 错误

具有嵌套属性的主干 Stickit

带有stickit.js的backbone.js嵌套对象属性

Stickit:如何在每个模型后触发更改事件 -> 视图更改