如何将backbone.js视图重用为托管小部件?

时间:2014-05-29 06:33:30

标签: javascript backbone.js widget

我的公司运行一个建立在backbone.js框架之上的电子商务网站。虽然我不是网络程序员,但我知道网站中的每个模块(类别页面,产品页面)都是使用相关的视图/模板对来呈现的。我们希望向发布商网站提供托管我们产品页面的小部件。据我所知,这需要托管网站下载的一些js代码才能显示小部件。是否有可能从网站代码库中提取相关的视图/模板片段并使其在该js代码中独立存在?我想它需要将相关的css和js库注入调用页面,是否有一些框架可以简化这个过程?

谢谢!

1 个答案:

答案 0 :(得分:0)

<强>更新

如何使用backbone和requirejs注入css和图像文件。

第1步:

使用Backbone Model,Backbone View,下划线模板以及最后调用模块的main.js初始化产品模块的整体结构。

_Note__:我按模块组织我的结构,即product/model.jsproduct/view.js,尽管您可以根据需要自由组织。 通常看到的是models/productModel.jsviews/product.js

   // @file: product/model.js
   // @info: Given a product model:
   var ProductModel = Backbone.Model.extend({ [...] });

   // @file: product/view.js
   // @info: Given a product view:
   var ProductView = Backbone.View.extend({ });

   // @file: layouts/template/productView.html
   // @info: Template view
   <link rel="stylesheet" type="text/css" href="asset/css/product/item.css">
   <script type="text/template" id="product-view">
       <div class="product details">
          <h2><%= name %></h2>
          <img class="thumb" src="<%= src %>">
          <div class="price"><%= price %></div>
       </div>
   </script>

   // @file: main.js
   // instanciate the model
   var productModel, productView;
   productModel = new ProductModel({ 
       id: 1, 
       name: "myProduct", 
       src: "assets/image/my_product.png",
       price: 321,
   });

   productView = new ProductView({
       model: productModel
   });

第2步:

添加require.js以异步加载js文件:

   // @file: index.html
   // @info: display root file
   <!DOCTYPE html>
   <html lang="en">
   <head>
       [...]
   </head>
   <body>
   [...]
   <!-- load the requirejs lib -->
   <script src="assets/vendor/require.js" data-main="assets/js/main.js" />
   </body>

在main.js中,我们需要配置requirejs lib。 首先,填充所需的库(骨干,下划线,jquery)。

   // @file: main.js
   // add requirejs config, which bind the needed libraries
   require.config({
       paths: {
           jquery: "../vendor/jquery",
           underscore: "../vendor/underscore",
           backbone: "../vendor/backbone",
           // requirejs text module
           // https://github.com/requirejs/text
           text: "../vendor/text"
       },
       shim: {
           jquery: {
               exports: "$"
           },
           underscore: {
               exports: "_"
           },
           backbone: {
               // Backbone needs these dependencies
               // so when we require(["backbone"])
               // it will also load jquery and underscore
               deps: ["jquery", "underscore"],
               exports: "Backbone"
           }
       },
   });
   // instanciate the model
   require(
      ["Backbone", "product/view", "product/model"],
      function (Backbone, ProductView, ProductModel) {
          var productModel, productView;
          productModel = new ProductModel({ 
             id: 1, 
             name: "myProduct", 
             src: "assets/image/my_product.png",
             price: 321,
         });

        productView = new ProductView({
           model: productModel
        });
      }
    );

需要对产品Backbone文件执行相同的操作:

// @file: product/model.js
define(["backbone"], function (Backbone) {
    var ProductModel = Backbone.Model.extend({ [...] });
    return ProductModel; 
});

// @file: product/view.js
define(
     ["backbone", "product/model", "text!layouts/template/productView.html"],
     function (Backbone, ProductModel, ProductTemplate) {
         var ProductView = Backbone.View.extend({ 
             [...]
             template: _.template(ProductTemplate),
             initialize: function (data) {
                 this.model = data.model;
                 return this;
             },
             render: function () {
                this.$el.html(this.template(this.model.toJSON()));
             }
         });
         return ProductView;
     }
);

第3步(优化和建议):

将此视为可选。

Backbone非常棒,因为它很轻巧。您可以使用Backbone.Native作为jquery的替换来使其更轻量级。

您甚至可以通过ExoJs替换Backbone来删除jquery和下划线依赖项。

您可以异步加载图片:

LazyLoad

更新layouts/template/productView.html

       // @file: layouts/template/productView.html
       // @info: Template view
       [...]
       <script type="text/template" id="product-view">
           <div class="product details">
              <h2><%= name %></h2>
              <img class="thumb lazy" src="assets/image/blank.gif" data-src="<%= src %>" height="<%= image.height %>" width= "<%= image.width %>">
              <div class="price"><%= price %></div>
           </div>
       </script>

更新main.js

  require.config({
       paths : { 
           [...],
           "lazyload": "../js/vendor/lazyload"

  });
  require(
      ["Backbone", "lazyload", "product/view", "product/model"],
      function (Backbone, LazyLoad, ProductView, ProductModel) {
          var productModel, productView;
          productModel = new ProductModel({ 
             id: 1, 
             name: "myProduct", 
             src: "assets/image/my_product.png",
             price: 321,
             image: {
                 width: "100px",
                 height: "100px"
             }
          });

          productView = new ProductView({
             model: productModel
          });
      }
    );

对于css,您可能已经注意到,我在模板视图中加载了一个css模块。 这不是最佳的,因为它可以更好地连接成一个大的css文件,以减少http请求的数量。

加载模块css的目的是:当你完成加载&#34;核心&#34; css文件,你可以异步加载一部分css。因此,您可以快速获得基本内容,然后您可以获得每个内容的详细信息。

删除layouts/template/productView.html中css文件的链接。 在requirejs路径中添加Toast。 实例化模型时添加额外的css属性。

productModel = new ProductModel({
    css: "asset/css/product/item.css"
    [...]
});

替换product/view.js

// @file: product/view.js
define(
     ["backbone", "toast", "product/model", "text!layouts/template/productView.html"],
     function (Backbone, Toast, ProductModel, ProductTemplate) {
         var ProductView = Backbone.View.extend({ 
             [...]
             template: _.template(ProductTemplate),
             initialize: function (data) {
                 this.model = data.model;
                 Toast(this.model.css);
                 return this;
             },
             render: function () {
                this.$el.html(this.template(this.model.toJSON()));
             }
         });
         return ProductView;
     }
);

requirejsbrowserify可以简化注入javascript的过程。

Backbone & Requirejs tuto

为了更好的模块化,请使用模板引擎。 underscore以及lodash都有一个。但你可以use a lot more

Requirejs不会异步加载css,yepnope.js会这样做。作为旁注,yepnope包含在modernizrjs中,如果你使用它。还有lazyloadl.jstoast