【问题标题】:Marionette CompositeView in the select>option context选择>选项上下文中的 Marionette CompositeView
【发布时间】:2015-12-19 23:07:47
【问题描述】:

我正在尝试设置一个简单的 Marionette 的 CompositeView。这就是我最终想要的:

%select#target-id
  %option{:value => "#{@id}"} = @name
  %option{:value => "#{@id}"} = @name 
  etc

在我的CompositeView 中,我指定了childViewContainer: select,并且我需要在此选择的选项中同时显示@name(为了便于阅读)和@id(为了相关事件)。由于默认 div 元素的性质,我可以在我的ItemView 中将tagName 指定为option

class New.TargetView extends App.Views.ItemView
    template: "path/to/template"
    tagName: 'option'

在模板中我只能传递要创建的选项元素的内容:= @name。这很好用,Marionette 为每个模型创建一个选项元素并用模型的名称填充它。问题是我也不知道如何传递属性,因为我无法指定尚未创建的元素的属性。

我还尝试在ItemView 上设置attributes 属性,如下所示:

attributes:
    value: "#{@id}"

它在技术上有效:选项填充有value="" 属性,但内容未定义。请指教。

【问题讨论】:

    标签: javascript backbone.js marionette


    【解决方案1】:

    当您使用attributes 时,我不确定部分。您应该传递哈希值或返回哈希值的函数,如Backbone view.attributes docs 中所述。

    attributes:
        value: "#{@id}"
    

    在旧货币中它是这样工作的。这里是jsfiddle

    attributes: function () {
        return {
            value: this.model.id
        };
    }
    

    【讨论】:

    • 我已经设法通过使用@$el.unwrap() 强制展开元素来解决问题,但这更干净,而且它一直很明显。非常感谢!
    【解决方案2】:

    CompositeViewItemView 是分别需要 Marionette 集合和模型的视图。当您创建CompositeView 时,您传递了一个模型集合,每个模型都将传递给相应的ItemView

    我的猜测是,这不是模板的问题,而是您设置数据的方式。据我所知,ItemView 没有attributes 选项,您必须使用正确格式的集合初始化CompositeView,或者使用serializeData 方法在ItemView 上创建新属性。

    在第一种情况下,您将执行以下操作:

    var SomeCompositeView = Marionette.CompositeView.extend({
        template: "your-template-name",
        childViewContainer: select
    });
    
    var SomeItemView = Marionette.ItemView.extend({
        template: "your-other-template",
        tagName: 'option'
    });
    
    // This collection can be retrieved from a database or anywhere else
    // Just make sure that the models have the fields you want
    var myCollection = new Backbone.Collection([{id: "someid1", name: "name1"}, {id: "someid2", name: "name2"}]);
    
    var view = new SomeCompositeView({collection: myCollection});
    

    在第二种情况下,您将拥有类似的东西,但在 ItemView 上,您将拥有:

    var SomeItemView = Marionette.ItemView.extend({
        template: "your-other-template",
        tagName: 'option',
        serializeData: function () {
            return { someAttribute: "someValue" }
        }
    }
    

    请记住,对于第二种方法,ItemView 必须有权访问您返回的值。 serializeData 仅用于重新格式化数据或对无法在模板上执行的数据执行操作。该模板只能访问您从 serializeData 返回的变量,与原始模型无关。

    【讨论】:

    • 感谢您的回复。本身没有问题,一切都按预期进行。我可以在我的ItemView 模板中写%option{:value => "#{@id}"} = @name,@id 和@name 都将被正确解析和显示。然而,在这种情况下,每个 %option{:value => "#{@id}"} = @name 都将被包裹在 Marionette 创建的 div 中,这将破坏 slecect>options HTML 结构。所以我需要找到在 single 元素中同时传递内容 属性的方法。
    • 听起来很奇怪。您能否添加其余代码(创建集合的位置,如何将其传递给视图等)?此外,在您最初的问题中,您没有提到任何关于包装div 的内容,但这听起来您的代码也有问题,因为如果您为两个视图都提供tagName,则不应创建div
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多