如何在一个Marionette js区域中显示/隐藏两个视图

时间:2017-06-25 10:17:00

标签: javascript backbone.js marionette

我的LayoutView两个区域名为过滤器区域和主要区域(内容区域) 。基于对过滤区域的选择,我需要将视图显示到主区域。

截至目前,我创建了一个视图以显示主要区域即当前年度视图,但我需要输入如何为我现在附加到我的问题面板中的其他线框创建视图。

CurrentYearView

PastYearView

// Application Bootstrap
var App = new Marionette.Application();

// Add a region
App.addRegions({
  main: "#app"
});

/*DATA*/
var data = {
  "accounts": [{
    "accountNumber": "AllAccounts",
    "assets": [{
        "assetName": "ASSET 1",
        "isin": "GB0008533564",
        "grossProfit": [{
          "assetCost": "500",
          "units": "10",
          "netGainLoss": "20"
        }]
      },
      {
        "assetName": "ASSET 2",
        "isin": "GB0008533565",
        "grossProfit": [{
          "assetCost": "500",
          "units": "10",
          "netGainLoss": "20"
        }]
      },
      {
        "assetName": "ASSET 3",
        "isin": "GB0008533566",
        "grossProfit": [{
          "assetCost": "500",
          "units": "10",
          "netGainLoss": "20"
        }]
      }
    ]
  }]
};

// AssetsModel
var AssetsModel = Backbone.Model.extend({});
//AssetsCollection - will contain the assets array
var AssetsCollection = Backbone.Collection.extend({
  model: AssetsModel,
  getAssetCost: function() {
    var assetCost = 0;
    this.each(function(model) {
      _(model.get('grossProfit')).each(function(gross) {
        assetCost += parseInt(gross.assetCost, 10);
      });
    });
    return assetCost;
  },
  getUnits: function() {
    var units = 0;
    this.each(function(model) {
      _(model.get('grossProfit')).each(function(gross) {
        units += parseInt(gross.units, 10);
      });
    });
    return units;
  },
  getNetGainLoss: function() {
    var netGainLoss = 0;
    this.each(function(model) {
      _(model.get('grossProfit')).each(function(gross) {
        netGainLoss += parseInt(gross.netGainLoss, 10);
      });
    });
    return netGainLoss;

  }
});

// AccountsModel - unique idAttribute will be accountNumber and setting the assets key of AccountsModel to AssetsCollection
var AccountsModel = Backbone.Model.extend({
  idAttribute: "accountNumber",
  initialize: function(response) {
    this.set('assets', new AssetsCollection(response.assets));
  }
});

// AccountsCollection - will be containg the Acccounts Array
var AccountsCollection = Backbone.Collection.extend({
  model: AccountsModel
});

// Passing the data.accounts to accountsCollection instance
var accountsCollection = new AccountsCollection(data.accounts);

// AppLayoutView - mainlayoutview of the application 
var AppLayoutView = Marionette.LayoutView.extend({
  template: Handlebars.compile($("#layout-view-template").html()),
  regions: {
    filter: "#filterArea",
    main: "#contentArea" // mainContentArea regiobn- will be containing two type of views:
    // 1. High level view, with multiple assets as table row's and only one object inside grossProfit
    // 2. Deep level view, with multiple objects inside assets array as table and mutliple objects inside grossProfit array
    //   (second point, need to be discussed for which i am raising question)
  },
  onRender: function() {
    this.showChildView("filter", new FilterView());
    this.showChildView("main", new TableCompositeView({
      collection: accountsCollection.get('AllAccounts').get('assets')
    }));
  }
});

var FilterView = Marionette.ItemView.extend({
  id: "filter-view",
  template: Handlebars.compile($('#filter-view-template').html())
});

var RowView = Marionette.ItemView.extend({
  tagName: "tr",
  template: Handlebars.compile($('#report-row-template').html())
});

var TableCompositeView = Marionette.CompositeView.extend({
  id: "report-area-view",
  tagName: "section",
  template: Handlebars.compile($("#report-view-template").html()),
  childView: RowView,
  childViewContainer: "#childWrapper",
  templateHelpers: function() {
    var totalAssetCost = this.collection.getAssetCost();
    var totalUnits = this.collection.getUnits();
    var totalNetGainLoss = this.collection.getNetGainLoss();
    return {
      totalAssetCost: totalAssetCost,
      totalUnits: totalUnits,
      totalNetGainLoss: totalNetGainLoss
    }
  }
});



var layoutView = new AppLayoutView();

// Render the layoutView to the main Region
App.getRegion('main').show(layoutView);

App.start();
.container {
  padding-top: 10px;
}
<div class="container">
  <div class="row">
    <div class="col-md-12">
      <div id="app"></div>
    </div>
  </div>
</div>

<!--TEMPLATES -->
<script id="layout-view-template" type="text/handlebars-template">
  <section>
    <div id="filterArea"> </div>
    <div id="contentArea"> </div>
  </section>
</script>

<script id="filter-view-template" type="text/handlebars-template">
  <div class="well">
    <input type="radio" name="currentYear" value="currentYear" /> Current year <br/><br/>
    <input type="radio" name="twoYears" value="pastYears" /> Past 2 year
  </div>
</script>

<script id="report-view-template" type="text/handlebars-template">
  <table class="table table-bordered table-hover">
    <thead>
      <tr>
        <th>Asset Name</th>
        <th>Asset Cost</th>
        <th>Units</th>
        <th>NetGainLoss</th>
      </tr>
    </thead>
    <tbody id="childWrapper"></tbody>
    <tfoot>
      <tr>
        <th>Total</th>
        <th>&#8377; {{totalAssetCost}}</th>
        <th>&#8377; {{totalUnits}}</th>
        <th>&#8377; {{totalNetGainLoss}}</th>
      </tr>
    </tfoot>
  </table>
</script>

<script id="report-row-template" type="text/handlebars-template">
  <td>{{assetName}}</td>
  {{#grossProfit}}
  <td>{{assetCost}}</td>
  <td>{{units}}</td>
  <td>{{netGainLoss}}</td>
  {{/grossProfit}}
</script>

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.3.3/backbone-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.marionette/2.4.2/backbone.marionette.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.0/handlebars.min.js"></script>

请使用以下数据显示过去两年的视图,只有很小的变化,只有grossProfit数组对象增加了。

var data = {
  "accounts": [{
    "accountNumber": "AllAccounts",
    "assets": [{
        "assetName": "ASSET 1",
        "isin": "GB0008533564",
        "grossProfit": [{
            "assetCost": "500",
            "units": "10",
            "netGainLoss": "20"
          },
          {
            "assetCost": "500",
            "units": "10",
            "netGainLoss": "20"
          }

        ]
      },
      {
        "assetName": "ASSET 2",
        "isin": "GB0008533565",
        "grossProfit": [{
            "assetCost": "500",
            "units": "10",
            "netGainLoss": "20"
          },
          {
            "assetCost": "500",
            "units": "10",
            "netGainLoss": "20"
          }

        ]
      },
      {
        "assetName": "ASSET 3",
        "isin": "GB0008533566",
        "grossProfit": [{
            "assetCost": "500",
            "units": "10",
            "netGainLoss": "20"
          },
          {
            "assetCost": "1000",
            "units": "10",
            "netGainLoss": "20"
          }

        ]
      }
    ]
  }]
};

1 个答案:

答案 0 :(得分:0)

案例1:如果您必须在主要区域内显示完全不同的复合视图,则必须创建一个单独的布局&#39; ResultLayout&#39;应该在主区域中呈现。您可以初始化ResultLayout中的复合视图,并在更改过滤器时渲染所需的复合视图。(对于不同的过滤器,数据是静态的情况) BR />

如果是动态数据
案例2:如果必须在主区域内显示完全不同的复合视图,则必须创建单独的布局&#39; ResultLayout&#39;应该在主区域中呈现。您可以在更改过滤器时呈现所需的复合视图 第一次,您可以显示所选的默认过滤器,并在主区域的布局(ResultLayout)内渲染相应的合成视图。
在过滤器更改时,您可以从FilterView中触发事件,该事件将在ResultLayout中监听(使用过滤器参数),根据过滤器获取集合,然后您可以在&#39; ResultLayout&#39;区域内渲染相应的复合视图。
层次结构如下:

LayoutView - &gt;过滤区域和主区域

主要地区 - &gt; ResultLayout

ResultLayout - &gt; CompositeView1或CompositeView2(取决于过滤器。)

案例3:如果你必须保持复合视图相同,那么你只需要更新集合并渲染视图。

我希望这有帮助!