javascript - 我的第一个主干模型/ View 。我在正确的轨道上吗?

标签 javascript backbone.js

目标是构建一个用户界面来选择 T 恤的品牌、尺码和颜色。并非所有颜色都适用于每个尺码,也并非所有尺码/颜色都适用于每个品牌。

所以基本的 UI 是品牌、尺寸和颜色的三个选择元素。

在阅读了一堆教程之后,我开始为品牌、尺寸和颜色创建模型,为每个品牌、尺寸、颜色和 View 创建集合,并编写代码来连接它们……有点迷路了头脑。

第二次尝试在这里,我创建了一个“Confg”模型和一个“Config” View 。模型作为当前品牌、尺寸和颜色的属性,以及当前可选择的品牌、型号和颜色的属性。

作为经验丰富的 backbone.js 专家,您会这样处理这个问题吗?

这是模型。基本上,我“手动”处理在 setMake 方法中获取正确的尺寸/颜色,并在 setSize 方法中更正颜色,然后对模型进行必要的更改。

var design_id = 2; // set server-side

var ConfigModel = Backbone.Model.extend({

    initialize: function(){
      this.baseUrl = "/designs/" + design_id + "/configure/";
    },

    setMake: function(make_id){
      var me = this;
      var make = _.find(this.get("makes"), function(el){ 
                  return el.id == make_id });
      // aggregate changes to the model:         
      var changes = {
        "make": make
      };
      // get current make/size/color:
      var cur_make_id = make.id;
      var cur_size_id = this.get("size").id;
      var cur_color_id = this.get("color").id;

      // get sizes for the current make:
      $.getJSON(me.baseUrl + "makes/" + cur_make_id + "/sizes/",
           function(data){
            changes.sizes = data;
            if(!_.find(data, function(el){ 
                  return el.id == cur_size_id })){
            // the currently selected size is not available, 
            // so use the first size
            changes.size = data[0];
            cur_size_id = changes.size.id;
          }
        // and get the colors for the current make and size:
        $.getJSON(me.baseUrl + "makes/" + cur_make_id 
               + "/sizes/" + cur_size_id + "/colors/",
             function(data){
               changes.colors = data;
               if(!_.find(data, 
                      function(el){ 
                         return el.id == cur_color_id })){
                          // the currently selected color 
                          // is not available, 
                          //so use the first one in the list
                     changes.color = data[0];
                       }
                me.set(changes);
              });
         });
      },

    setSize: function(size_id){
      // retrieve colors for the new size
      var me = this;
      var size = _.find(this.get("sizes"), 
              function(el){ return el.id == size_id });
      var changes = {
        "size": size
      };

      var cur_make_id = this.get("make").id;
      var cur_size_id = size.id;
      var cur_color_id = this.get("color").id;

      $.getJSON(me.baseUrl + "makes/" + cur_make_id + 
                "/sizes/" + cur_size_id + "/colors/",
          function(data){
             changes.colors = data;
             if(!_.find(data, 
                function(el){ 
                  return el.id == cur_color_id })){
             changes.color = data[0];
          }
          me.set(changes);
      });
    },

    setColor: function(color_id){
      var color = _.find(this.get("colors"), 
             function(el){ 
                return el.id == color_id });
      this.set({"color": color});
    }
  });

这是模型实例。初始默认值是在服务器端设置的:

  var Config = new ConfigModel({
    design_id: 2,

    make: {"id": 1, "name": "Men's Organic Cotton Tee"},
    size: {"id": 4, "name": "L"},
    color: {"id": 2, "name": "Black"},

    makes: [{"id": 2, "name": "Women's Organic Cotton Tee"}, 
            {"id": 1, "name": "Men's Organic Cotton Tee"}],
    sizes: [{"id": 2, "name": "S"}, 
            {"id": 3, "name": "M"}, 
            {"id": 4, "name": "L"}],
    colors:  [{"id": 2, "name": "Black"},  
             {"id": 3, "name": "red"}]

  });

这是 View 。我认为这非常简单。绑定(bind)到选择元素上的更改事件并在模型上调用 setMake 或 setSize,然后监听来自模型的更改事件:

var ConfigView = Backbone.View.extend({
        el: $("#config"),

        optionsTemplate: _.template($("#options-template").html()),

        events:{
          "change #make select": "onChangeMake",
          "change #size select": "onChangeSize",
          "change #color select": "onChangeColor"
        },

        initialize: function(){
          Config.bind("change:makes", this.updateMakes, this);
          Config.bind("change:sizes", this.updateSizes, this);
          Config.bind("change:colors", this.updateColors, this);
        },

        render: function(){
        //console.log("ConfigureView.render");
        this.updateSelect("make");
        this.updateSelect("size");
        this.updateSelect("color");
        },

        updateMakes: function(){ 
          this.updateSelect("make");
        },

        updateSizes: function(){ 
          this.updateSelect("size"); 
        },

        updateColors: function(){ 
          this.updateSelect("color"); 
        },

        updateSelect: function(which){
          // updates the select specified by "which"
          this.$("#" + which + " select").html(this.optionsTemplate({
            chosen:Config.get(which),
            options:Config.get(which + "s")
          }));
        },

        onChangeMake: function(){
        Config.setMake(this.$("#make select").val());
        },

        onChangeSize: function(){
        Config.setSize(this.$("#size select").val());
        },

        onChangeColor: function(){
          Config.setColor(this.$("#color select").val());
        }
    });

    var app = new ConfigView();
    app.render();

最佳答案

有人告诉我,您的 $.getJSON 函数应该改为 Backbone Collections。

http://documentcloud.github.com/backbone/#Collection

使用集合而不是您正在做的事情将使您的应用程序更易于阅读和管理。同样使用 $.getJSON 而不是 backbone 的集合可以避免 backbone 的单一模型。

这实际上是我不久前在 StackOverflow 上发布的一个问题,它可能与我所说的有关。看看 Julien 是怎么说的。

Integrating JSON feed with Backbone JS

关于javascript - 我的第一个主干模型/ View 。我在正确的轨道上吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8687236/

相关文章:

Javascript 函数只调用一次

javascript - Redux-form 不格式化发布数据和 [object Object] 问题

javascript - 如何使用按位运算符 & 评估偶数和奇数

javascript - Backbone.js 集合选项

javascript - 在方法内交换变量

javascript - 为什么我在localStorage中设置的和我得到的不一样?

Backbone.js 方法来管理 UI 状态/处理 UI 中的选择

javascript - 每次收到 XHR 请求时,如何使用 JQuery AjaxSetup 将 "csrf"设置为参数?

javascript - 未捕获的类型错误 : View is not a constructor

javascript - 引用错误: document is not defined at compile/Electron