Layout implementation for Dojo MVC

2019-04-07 01:42发布

问题:

I started a dojo project from scratch by trying using good practice from the very beginning. I'm really new to dojo toolkit, so I'm walking through lots of documentations and samples which leave me with a lots of cool stuff but no way on how to implement an architecture for future dev (or add-ons). I have searched the web and found this dojo boilerplate project which seems to be a good start for putting it all together, but I wanted something more, I wanted to implement the MVC pattern (I have lots of experience with JAVA and Ruby on rails dev) in my application and came across this very cool example. So, I created something like this which seems a pretty legit way to organize my project. Correct me, if I'm wrong.. or you have a better approach.

Now, I am ready to start. I have tried a couple of tutorials on dojo toolkit website. Run wonderfully when you only have one page. But right now, I was wondering how would I implement this layout tutorial into my own application. I want this kind of layout to be my main layout for my application (so, I tried to had those pieces of code into my index.html),

<div
        id="appLayout" class="demoLayout"
        data-dojo-type="dijit.layout.BorderContainer"
        data-dojo-props="design: 'headline'">
    <div
            class="centerPanel"
            data-dojo-type="dijit.layout.ContentPane"
            data-dojo-props="region: 'center'">
        <div>
            <h4>Group 1 Content</h4>
            <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
        </div>
        <div>
            <h4>Group 2 Content</h4>
        </div>
        <div>
            <h4>Group 3 Content</h4>
        </div>
    </div>
    <div
            class="edgePanel"
            data-dojo-type="dijit.layout.ContentPane"
            data-dojo-props="region: 'top'">Header content (top)</div>
    <div
        id="leftCol" class="edgePanel"
        data-dojo-type="dijit.layout.ContentPane"
        data-dojo-props="region: 'left', splitter: true">Sidebar content (left)</div>
</div>

but it doesn't get:

require(["dijit/layout/BorderContainer", "dijit/layout/TabContainer",
        "dijit/layout/ContentPane", "dojo/parser"]);

So the result is basically the div and my text, but no layout whatsoever. What am I missing?

My solution: I would create only a div on my index (e.g "container") and feed him from the loader (app/run.js), (which call another script called main), this main.js file is using the concept of AMD (which I'm beginning to be familiar), and he's handling the creation of any instance of my application. So, for example, I could create a specific view for my layout and instance it on that file...

回答1:

I use also dojo boilerplate project for my applications and this is my main.js:

define([ 'dojo/has', 'require', 'dojo/_base/sniff' ], function (has, require) {
    var app = {};

    if (has('host-browser') && isCompatible()) {

        require([ './EntryPoint', 'dojo/domReady!' ], function (EntryPoint) {
            app.entryPoint = new EntryPoint().placeAt(document.body);
            app.entryPoint.startup();
    } else {
        window.location = "/admin/browser/";
    }

    function isCompatible() {
        // browser compatibility check here
    }
});

My EntryPoint module/class is a widget, i.e. EntryPoint.js looks like:

define([
    "dojo/_base/declare",
    "dijit/_Widget",
    "dijit/_TemplatedMixin",
    "dijit/_WidgetsInTemplateMixin",

    "dojo/i18n!app/nls/main",
    "dojo/text!./ui/templates/EntryPoint.html",

    "dijit/layout/BorderContainer",
    "dijit/layout/StackContainer",
    "dijit/layout/ContentPane"
], function(
    declare,
    _Widget,
    _TemplatedMixin, 
    _WidgetsInTemplateMixin,

    i18n,
    template
){
    return declare([_Widget, _TemplatedMixin, _WidgetsInTemplateMixin], {

        templateString: template,
        i18n: i18n,

        postCreate: function() {
            //...
        }

    });
});

Finally my EntryPoint.html:

<div style="height:100%;">
  <div
      data-dojo-type="dijit.layout.BorderContainer"
      data-dojo-props="design: 'sidebar', gutters: false"
      data-dojo-attach-point="mainContainer"
      style="height:100%;"
    >

    <div
      data-dojo-type="dijit.layout.BorderContainer"
      data-dojo-props="region: 'left', splitter: true, design: 'headline', gutters: false"
      data-dojo-attach-point="sidebarPane"
      class="sidebarPane"
    >

      <div 
          data-dojo-type="dijit.layout.ContentPane"
          data-dojo-props="region: 'center'"
      >

        <div class="sidebarSection">${i18n.title.public_}</div>
        <div
            id="sidebar-posts"
            data-dojo-type="app.widget.SidebarItem"
            data-dojo-props="iconClass: 'sidebarIconPosts', value:'posts', name: 'sidebar'">
          ${i18n.title.posts}
        </div>
        <div
            id="sidebar-pages"
            data-dojo-type="app.widget.SidebarItem"
            data-dojo-props="iconClass: 'sidebarIconPages', value:'pages', name: 'sidebar'">
          ${i18n.title.pages}
        </div> 

[...]

The advantage of using Widget as your main layout:

  • html template works out of the box with dojo build system
  • you can use data-dojo-attach-point and data-dojo-attach-event in your layout template
  • you can use ${i18n.title.members} for string substitution in html