我的第一个骨干模型/视图。我是在正确的轨道上吗?

时间:2011-12-31 08:45:36

标签: javascript backbone.js

目标是构建一个UI来选择T恤的品牌,尺寸和颜色。并非所有颜色都适用于所有尺寸,并非所有尺寸/颜色都适用于每种尺寸。

因此,基本用户界面是制作,尺寸和颜色的三个选择元素。

在阅读了一堆教程之后,我开始创建Make,Size和Color的模型,以及每个模型的Makes,Sizes,Colors和视图的集合,以及连接它们的代码。心神。

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

这是你,你是一位经验丰富的骨干专家,你会接近这个吗?

这是模型。基本上,我“手动”处理在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"}]

  });

这是观点。我认为这非常简单..绑定到选择元素上的更改事件并在模型上调用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();

1 个答案:

答案 0 :(得分:0)

有些东西告诉我你的$ .getJSON函数应该是Backbone Collections。

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

使用集合代替您正在执行的操作将使您的应用程序更易于阅读和管理。还使用$ .getJSON而不是骨干的集合,远离骨干的唯一模型。

这实际上是我不久前在StackOverflow上发布的一个问题,可能与我说的有关。看看朱利安不得不说的话。

Integrating JSON feed with Backbone JS