Dojo -- Getting Started篇之Modern Dojo(现代化Dojo)

“modern”dojo

声明:本文是基于dojo官方文档,加上自己的理解整理出来的。

本文会简单介绍一下,dojo1.10带来的新的变化。

准备开始

Dojo1.7是一个重要里程碑,整体的架构更加灵活,也更加“现代化”。Dojo1.10则在1.7的基础上,引入了一些新的特性和概念,例如dojo/on。如果你想让dojo代码跑的更快,更加高效,并且想提高代码的可维护性,那就赶紧升级到dojo1.10吧。另外,dojo是完全向后兼容的。

新hello world

modern dojo其中一个核心概念是:禁止使用全局命名空间。dojo为了向后兼容,原先放置在全局命名空间中的函数和变量,仍然是可用的,但在新版的dojo中,最好别用。因为其他开发人员随时可能自己定义一个名字跟全局命名空间中的函数名一样的函数出来,这样会造成冲突的。像下面的使用方式就不推荐。

dojo.* or dijit.* or dojox.*

其实只需简单的引入dojo.js,然后使用require() 方法加载其他模块即可。

另一个核心概念是:同步操作慢,异步操作快。dojo 1.7(包括1.7),支持Asynchronous Module Definition (AMD)的概念,可以使用require()来异步加载用到的dojo 模块。

旧版用法

  dojo.ready(function(){
    dojo.byId("helloworld").innerHTML = "Hello World!";
  });

新版用法

require(["dojo/dom", "dojo/domReady!"], function(dom){
    dom.byId("helloworld").innerHTML = "Hello New World!";
  });

其中的require 方法有两个参数,第一个是模块id列表,另一个是函数,在这个函数会存放模块的引用。
细心的读者会发现dojo/doReady! 是没法在函数中引用的,原因是,dojo/doReady! 是一个dojo插件,它会与dojo的加载器进行交互,保证页面中的dom结构都解析完毕后,函数才开始调用。如果你需要使用dojo操作dom,那么最好使用该插件。

Dojo基础以及核心

在旧版本的dojo中,dojo.js是一个臃肿庞大的脚本,里面存放了非常多的dojo方法。所以我们应该尽量避免使用dojo.*的方式。

dojoconfig对象中有一个async属性,默认值是false,这意味着,当使用dojo时,所有dojo基础模块将会被加载。为了提高应用的响应速度,可以把async设置为true,这样这些基础模块不会被自动的加载到。

由于旧版的dojo.js过于庞大,新版的dojo中,已经将里面的代码模块化,使用方式也不同了。如下:

旧的用法

dojo.require("dojo.string");
dojo.byId("someNode").innerHTML = dojo.string.trim("  I Like Trim Strings ");

新的用法

require(["dojo/dom", "dojo/string", "dojo/domReady!"], function(dom, string){
    dom.byId("someNode").innerHTML = string.trim("  I Like Trim Strings ");
  });

事件以及切面

在”modern dojo”中,dojo/on 用于事件处理,用来代替原来的dojo.connect() , 而dojo/aspect 则运用了AOP的概念,可以进行方法的拦截。

旧版用法

<script>
    dojo.require("dijit.form.Button");

    myOnClick = function(evt){
      console.log("I was clicked");
    };

    dojo.connect(dojo.byId("button3"), "onclick", myOnClick);
  </script>
  <body>
    <div>
      <button id="button1" type="button" onclick="myOnClick">Button1</button>
      <button id="button2" data-dojo-type="dijit.form.Button" type="button"
        data-dojo-props="onClick: myOnClick">Button2</button>
      <button id="button3" type="button">Button3</button>
      <button id="button4" data-dojo-type="dijit.form.Button" type="button">
        <span>Button4</span>
        <script type="dojo/connect" data-dojo-event="onClick">
          console.log("I was clicked");
        </script>
    </div>
  </body>

modern dojo用法

<script>
    require([
        "dojo/dom",
        "dojo/on",
        "dojo/parser",
        "dijit/registry",
        "dijit/form/Button",
        "dojo/domReady!"
    ], function(dom, on, parser, registry){
        var myClick = function(evt){
            console.log("I was clicked");
        };

        parser.parse();

        on(dom.byId("button1"), "click", myClick);
        on(registry.byId("button2"), "click", myClick);
    });
  </script>
  <body>
    <div>
      <button id="button1" type="button">Button1</button>
      <button id="button2" data-dojo-type="dijit/form/Button" type="button">Button2</button>
      <button id="button3" data-dojo-type="dijit/form/Button" type="button">
        <div>Button4</div>
        <script type="dojo/on" data-dojo-event="click">
          console.log("I was clicked");
        </script>
      </button>
    </div>
  </body>

在旧版的dojo中,如果你想在某个js方法执行后,执行某个方法,可以如下这样做:

var callback = function(){
    // ...
  };
  //myInstance表示目标对象,execute表示目标对象中的方法,callback表示,execute执行后需要调用的方法。
  var handle = dojo.connect(myInstance, "execute", callback);
  // ...
  dojo.disconnect(handle);

modern dojo可以使用切面。

 require(["dojo/aspect"], function(aspect){
    var callback = function(){
      // ...
    };
    var handle = aspect.after(myInstance, "execute", callback);
    // ...
    handle.remove();
  });

发布与订阅

发布订阅自1.7版本便开始有了,后续版本又做了一些改进。

旧版用法

// To publish a topic
  dojo.publish("some/topic", [1, 2, 3]);

  // To subscribe to a topic
  var handle = dojo.subscribe("some/topic", context, callback);

  // And to unsubscribe from a topic
  dojo.unsubscribe(handle);

新版用法

require(["dojo/topic"], function(topic){
    // To publish a topic
    topic.publish("some/topic", 1, 2, 3);

    // To subscribe to a topic
    var handle = topic.subscribe("some/topic", function(arg1, arg2, arg3){
      // ...
    });

    // To unsubscribe from a topic
    handle.remove();
  });

下面具体举个例子

require(["dojo/topic", "dojo/dom", "dojo/on", "dojo/domReady!"],
function(topic, dom, on){

  var handle = topic.subscribe("some/topic", function(e){
    dom.byId("output").innerHTML = "I received: " + e.msg;
    handle.remove();
  });

  on(dom.byId("publish"), "click", function(){
    topic.publish("some/topic", { msg: "hello world" });
  });

});
<button type="button" id="publish">Publish "some/topic"</button>
<div id="output">Nothing Yet...</div>

Dojo异步编程

可以使用Deferredpromise api来处理。


旧版用法

 function createMyDeferred(){
    var myDeferred = new dojo.Deferred();
    setTimeout(function(){
      myDeferred.callback({ success: true });
    }, 1000);
    return myDeferred;
  }

  var deferred = createMyDeferred();
  deferred.addCallback(function(data){
    console.log("Success: " + data);
  });
  deferred.addErrback(function(err){
    console.log("Error: " + err);
  });



新版用法

require(["dojo/Deferred"], function(Deferred){
    function createMyDeferred(){
      var myDeferred = new Deferred();
      setTimeout(function(){
        myDeferred.resolve({ success: true });
      }, 1000);
      return myDeferred;
    }

    var deferred = createMyDeferred();
    deferred.then(function(data){
      console.log("Success: " + data);
    }, function(err){
      console.log("Error: " + err);
    });
  });

发送Ajax请求



旧版用法

dojo.xhrGet({
    url: "something.json",
    handleAs: "json",
    load: function(response){
      console.log("response:", response);
    },
    error: function(err){
      console.log("error:", err);
    }
  });



新版用法

require(["dojo/request"], function(request){
    request.get("something.json", {
      handleAs: "json"
    }).then(function(response){
      console.log("response:", response);
    }, function(err){
      console.log("error:", err);
    });
  });

操作Dom的模块

模块
dojo/dom
dojo/dom-attr
dojo/dom-class
dojo/dom-construct
dojo/dom-form
dojo/io-query
dojo/dom-geometry
dojo/dom-prop
dojo/dom-style
require(["dojo/dom", "dojo/dom-attr"], function(dom, domAttr){
    var node = dom.byId("someNode");

    // Retrieves the value of the "value" DOM attribute
    var value = domAttr.get(node, "value");

    // Sets the value of the "value" DOM attribute
    domAttr.set(node, "value", "something");
  });

Dijit and Widgets

如果你想观察某个元素属性值的变化,可以使用dojo/Stateful中的类。

 require(["dijit/form/Button", "dojo/domReady!"], function(Button){
    var button = new Button({
      label: "A label"
    }, "someNode");

    // 在button.label上设置一个观察者
    var handle = button.watch("label", function(attr, oldValue, newValue){
      console.log("button." + attr + " changed from '" + oldValue + "' to '" + newValue + "'");
    });

    // 获取当前label
    var label = button.get("label");
    console.log("button's current label: " + label);

    // 值发生改变,调用观察者
    button.set("label", "A different label");


    handle.unwatch();

    button.set("label", "Even more different");
  });

Parser

在dojo1.10里,可以显示的使用解析器,无需在dojo config里配置parseOnLoad: true

   require(["dojo/parser", "dojo/domReady!"], function(parser){
        parser.parse();
    });

另外使用data-dojo-type替代dojoType,至于元素的属性则可以使用data-dojo-props来指定。

 <button data-dojo-type="dijit/form/Button" tabIndex=2
      data-dojo-props="iconClass: 'checkmark'">OK</button>

1.10中,你可以向下面这样监听元素属性的变化。

<button data-dojo-type="dijit/form/Button" type="button">
    <span>Click</span>
    <script type="dojo/on" data-dojo-event="click" data-dojo-args="e">
      console.log("I was clicked!", e);
      this.set("label", "Clicked!");
    </script>
    <script type="dojo/watch" data-dojo-prop="label" data-dojo-args="prop, oldValue, newValue">
      console.log("button: " + prop + " changed from '" + oldValue + "' to '" + newValue + "'");
    </script>
  </button>

本文到此完结。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值