1. 程式人生 > >ember.js提供的基礎服務介紹

ember.js提供的基礎服務介紹

write by yinmingjun,引用請註明。

ember.js作為一個全功能的javascript的MVC框架,需要維護大量的程式碼,基於write less use more的原則,ember.js不可避免的抽象了大量的基礎服務,以便最大程度的複用程式碼。而對於希望讀懂ember.js程式碼的開發人員,這部分程式碼可能會成為理解ember.js的設計意圖的障礙。因此,筆者在開始描述ember.js的特性的細節之前,選擇對ember.js中的基礎程式碼先做一個梳理,並相信理解這部分程式碼,對用好ember.js會有很大的幫助。

在這部分程式碼中,也包含ember.js對javascript語言潛力的挖掘,會看到很多javascript擅長的表述方式,對那些喜歡極致程式設計的開發人員,將會是一個很好的體驗過程。

下面我們按種類來介紹ember.js的基礎服務。

一、對除錯的支援

在開發的過程中,一般有限會考慮除錯支援相關的API,這是解決生產效率的關鍵要素。

在ember.js中,有下面的除錯API:

> Ember.assert 方法

定義

Ember.assert = function(desc, test) {
     if (!test) throw new Error("assertion failed: "+desc);
};

描述

在程式碼中設定斷言。如果斷言不是true,就丟擲異常,中止程式的執行。

Ember.assert在開發版的ember.js中,是斷言方法,在release版中,會被替換成空方法(與編譯系統中的assert類似),也就是說,Ember.assert是for開發的診斷工具。

引數

    desc      string型別,是傳遞給Ember.assert的診斷描述

    test       bool型別,如果為false,會引發斷言的異常

> Ember.warn方法

定義

Ember.warn = function(message, test) {
  if (!test) {
    Ember.Logger.warn("WARNING: "+message);


    if ('trace' in Ember.Logger) Ember.Logger.trace();
  }
};

描述

與Ember.assert類似,不過不像Ember.assert會丟擲異常並中止程式的執行,Ember.warn僅產生LOG。Ember.warn也是for開發的支援工具,在release版的ember.js中會被替換成空方法。

引數

message     string型別,是需要輸出的警告資訊

test             bool型別,如果為false,會引發輸出警告的資訊

> Ember.debug方法

定義

Ember.debug = function(message) {
  Ember.Logger.debug("DEBUG: "+message);
};

描述

在程式碼中輸出除錯資訊。在release版中,會被替換成空方法。

引數

message    string型別,是需要輸出的除錯資訊

> Ember.deprecate 方法

定義

Ember.deprecate = function(message, test) {

    //code .......

};

描述

與Ember.warn類似,將message會輸出到logger的warn級別,Ember.deprecate與Ember.warn差別是Ember.deprecate還會提供呼叫棧的資訊。在release版中,會被替換成空方法。

引數

message    string型別,是傳遞給Ember.deprecate的診斷資訊描述

test             bool型別,如果為false,會輸出警告資訊到logger

> Ember.deprecateFunc方法

定義

Ember.deprecateFunc = function(message, func) {
  return function() {
    Ember.deprecate(message);
    return func.apply(this, arguments);
  };
};

描述

返回一個包裝函式,用來包裝對引數中func的呼叫。

Ember.deprecateFunc用來產生API的廢棄的呼叫說明,並將對廢棄的API重定向到新的API。

例如,下面的Ember.none方法被Ember.isNone替代了,如果繼續呼叫Ember.none會產生警告資訊:

     Ember.none = Ember.deprecateFunc("Ember.none is deprecated. Please use Ember.isNone instead.", Ember.isNone);
在release版中,Ember.deprecateFunc的警告資訊被移除,只保留API的重定向功能。

引數

message    string型別,是需要輸出的警告資訊

func           function型別,是重定向的目標函式

二、LOG支援

ember.js通過Ember.Logger介面來提供LOG的支援,Ember.Logger的定義如下:

Ember.Logger的定義

Ember.Logger= {
  log:   consoleMethod('log')   || Ember.K,
  warn:  consoleMethod('warn')  || Ember.K,
  error: consoleMethod('error') || Ember.K,
  info:  consoleMethod('info')  || Ember.K,
  debug: consoleMethod('debug') || consoleMethod('info') || Ember.K
};

Ember.Logger的描述

Ember.Logger的規則很簡單,只是將資訊輸出到imports.console,在瀏覽器是輸出到全域性console函式之中。

替代Ember.Logger,只需要將其幾個方法重定向就OK了,就預設實現來說,對大多數人來說以及足夠用了,不過在大型系統中可能需要對Logger做整合。

三、物件複製&合併

在ember.js依賴的jquery中存在類似的服務,不過ember.js還是提供了,可能是因為物件複製的服務太基礎了。在javascript的簡單資料物件(POJO)的操作中,常見的操作是合併與複製,其中複製還可能需要做深度克隆。

ember.js通過Ember.merge方法支援物件的合併,通過Ember.copy支援物件的複製。

> Ember.merge方法

定義

Ember.merge = function(original, updates) {
    for (var prop in updates) {
        if (!updates.hasOwnProperty(prop)) { continue; }
        original[prop] = updates[prop];
    }
    return original;
};

描述

Ember.merge將updates中的內容合併到original物件之中。如果original中已經存在同名的屬性,會被updates中的內容覆蓋。

引數

original     object型別,是需要合併的目標

updates    object型別,是合併的資料來源

> Ember.copy方法

定義

Ember.copy = function(obj, deep) {
    // fast paths
    if ('object' !== typeof obj || obj===null) return obj; // can't copy primitives
    if (Ember.Copyable && Ember.Copyable.detect(obj)) return obj.copy(deep);
    return _copy(obj, deep, deep ? [] : null, deep ? [] : null);
};

描述

Ember.copy將複製obj中的內容,並返回克隆的物件。如果存在deep引數,並且其值為true,那麼會做深度的複製。

注意,如果obj不是物件,或者是null,

合併到original物件之中。如果original中已經存在同名的屬性,會被updates中的內容覆蓋。

引數

obj     object型別,是需要複製的物件

deep  bool型別,可忽略,如果為true表示是深度複製

四、程式碼的排程&執行

> Ember.onLoad方法

定義

Ember.onLoad= function(name, callback) {
    var object;

    loadHooks[name] = loadHooks[name] || Ember.A();
    loadHooks[name].pushObject(callback);

    if (object = loaded[name]) {
        callback(object);
    }
};

描述

ember.js支援對onload佇列的掛接,用於支援各個生命週期中的就緒事件的底層處理。和與Ember.onLoad方法配合的是Ember.runLoadHooks方法,用於執行一個名字對應的佇列中所有的callback方法。如果佇列以及執行過了,傳入的callback會立即被執行。

在ember.js中,有'Ember.Handlebars'、'application'、'Ember.Application'等幾個內部的佇列。

參考Ember.runLoadHooks方法:

Ember.runLoadHooks= function(name, object) {
    loaded[name] = object;

    if (loadHooks[name]) {
        forEach.call(loadHooks[name], function(callback) {
            callback(object);
        });
    }
};

引數

name      string型別,是load佇列的名字

callback funtion型別,是希望放到load佇列中的callback方法 

> Ember.run方法

定義

Ember.run= function(target, method) {
  var ret;

  if (Ember.onerror) {
    try {
      ret = backburner.run.apply(backburner, arguments);
    } catch (e) {
      Ember.onerror(e);
    }
  } else {
    ret = backburner.run.apply(backburner, arguments);
  }

  return ret;
};

描述

Ember.run方法執行指定物件的方法。ember.js提供Ember.run方法的主要目的是可以獲取到方法執行前後的事件,可以對繫結、變更等事件立即做出響應,還可以攔截程式碼執行過程中的異常,並將異常傳遞給Ember.onerror的全域性的錯誤的handler中。

ember.js通過backburner來封裝對執行的支援。

引數

target   object型別,可能為null,是method所在的物件。

methodfunction型別,target上的方法;或string型別,是target成員的名稱。

args       後續的所有引數,可省略,將在呼叫時傳遞給method。

> Ember.run.join方法

定義

Ember.run.join= function(target, method) {
  if (!Ember.run.currentRunLoop) {
    return Ember.run.apply(Ember.run, arguments);
  }

  var args = slice.call(arguments);
  args.unshift('actions');
  Ember.run.schedule.apply(Ember.run, args);
};

描述

如果不存在Ember.run.currentRunLoop的時候與Ember.run方法相同,如果有Ember.run.currentRunLoop就會將要執行的方法放到RunLoop的'actions'佇列中執行。 

說明

解釋一下,Ember.run方法每次執行的時候都會建立一個DeferredActionQueues的例項,作為執行的上下文,將當前的Ember.run.currentRunLoop的例項推入棧中儲存起來,並在執行完畢之後恢復Ember.run.currentRunLoop的值,也就是說,Ember.run.currentRunLoop總是代表當前的Ember.run方法的執行上下文。

引數

(同Ember.run方法)

> Ember.run.begin和Ember.run.end方法

定義

Ember.run.begin= function() {
  backburner.begin();
};

Ember.run.end= function() {
  backburner.end();
};

描述

是手工開啟/關閉ember.js的RunLoop的底層呼叫的API,一般使用的模式如下:

  Ember.run.begin();
  // code to be execute within a RunLoop
  Ember.run.end();

> Ember.run.schedule方法

定義

Ember.run.schedule= function(queue, target, method) {
  checkAutoRun();
  backburner.schedule.apply(backburner, arguments);
};

描述

Ember.run.schedule方法將指定物件的方法傳遞到指定的排程佇列中執行。

ember.js提供了'sync', 'actions', 'render', 'afterRender','destroy'五個佇列,三個佇列的執行次序與定義次序相同,sync最先,actions居中,destroy最後。ember.js的排程佇列在每次Ember.run方法的end期間執行(完callback之後)。

Ember.run.schedule方法一般是在ember.js內部使用。

引數

queue     string型別,是'sync', 'actions', 'render', 'afterRender','destroy'中的一個,佇列的執行次序與定義次序相同,sync最先,actions居中,destroy最後

target     object型別,可以為null,是method所在的物件。

method  function型別,target上的方法;或string型別,是target成員的名稱。

args        後續的所有引數,可省略,將在呼叫時傳遞給method。

> Ember.run.scheduleOnce方法

定義

Ember.run.scheduleOnce= function(queue, target, method) {
     checkAutoRun();
     return backburner.scheduleOnce.apply(backburner, arguments);
};

描述

Ember.run.schedule方法左右類似,差別是在語義上保證只調度執行一次(無論使用Ember.run.scheduleOnce新增排程專案幾次)

注意

使用匿名函式的時候要小心,因為每次執行的時候都返回返回不同的函式,在比較上會認為排程專案是不同的方法。如:

     Ember.run.scheduleOnce('actions', myContext,function(){ console.log("Closure"); });

引數

(參考Ember.run.schedule方法)

> Ember.run.once方法

定義

Ember.run.once= function(target, method) {
    checkAutoRun();
    var args = slice.call(arguments);
    args.unshift('actions');
    return backburner.scheduleOnce.apply(backburner, args);
};

描述

Ember.run.scheduleOnce的便捷方法,將提供的物件、方法排程到'actions'佇列執行。

引數

target     object型別,可以為null,是method所在的物件。

method  function型別,target上的方法;或string型別,是target成員的名稱。

args         後續的所有引數,可省略,將在呼叫時傳遞給method。

> Ember.run.later方法

定義

Ember.run.later= function(target, method) {
    return backburner.later.apply(backburner, arguments);
};

描述

延遲執行指定的方法,與setTimeout作用類似。呼叫的DEMO如下:

Ember.run.later(myContext, function(){
    // code here will execute within a RunLoop in about 500ms with this == myContext
  },500);

規定,最後一個引數是延遲的時間,單位是ms(毫秒)

引數

target        object型別,可以為null,是method所在的物件。

method    function型別,target上的方法;或string型別,是target成員的名稱。

args          後續的所有引數,可省略,將在呼叫時傳遞給method。

delay     最後一個引數是延遲的毫秒數。

> Ember.run.next方法

定義

Ember.run.next= function() {
    var args = slice.call(arguments);
    args.push(1);
    return backburner.later.apply(backburner, args);
};

描述

 是Ember.run.later的便捷方法,表示延遲執行方法。包裝的later中提供的延遲時間是1ms。

引數

target     object型別,可以為null,是method所在的物件。

method   function型別,target上的方法;或string型別,是target成員的名稱。

args         後續的所有引數,可省略,將在呼叫時傳遞給method。

> Ember.run.cancel方法

定義

Ember.run.cancel= function(timer) {
  return backburner.cancel(timer);
};

描述

取消Ember.run.later()或Ember.run.next()指定的延遲方法的執行,提供的timer引數應該是Ember.run.later()或Ember.run.next()的返回值。

引數

timer    object型別,應該是Ember.run.later()或Ember.run.next()的返回值。

> Ember.run.cancelTimers方法

定義

Ember.run.cancelTimers= function () {
  backburner.cancelTimers();
};

描述

取消所有的延遲方法的執行,一般用於ember.js執行環境的清理。

引數

五、對事件體系的支援

ember.js通過Ember.Evented這個Mixin對事件體系提供支援,而Ember.Evented又被混合到Ember.CoreView之中,也就是說所有的view都能使用Ember.Evented提供的方法。

> Ember.Evented Mixin

定義

Ember.Evented = Ember.Mixin.create({

    on: function(name, target, method) {
    Ember.addListener(this, name, target, method);
    return this;
  },

  one: function(name, target, method) {
    if (!method) {
      method = target;
      target = null;
    }

    Ember.addListener(this, name, target, method, true);
    return this;
  },

  trigger: function(name) {
    var args = [], i, l;
    for (i = 1, l = arguments.length; i < l; i++) {
      args.push(arguments[i]);
    }
    Ember.sendEvent(this, name, args);
  },

  fire: function(name) {
    Ember.deprecate("Ember.Evented#fire() has been deprecated in favor of trigger() for compatibility with jQuery. It will be removed in 1.0. Please update your code to call trigger() instead.");
    this.trigger.apply(this, arguments);
  },

  off: function(name, target, method) {
    Ember.removeListener(this, name, target, method);
    return this;
  },

  has: function(name) {
    return Ember.hasListeners(this, name);
  }
});

描述

簡單的說一下。

on方法:

用於設定event的handler,name對應事件的名稱,target和method合起來描述handler。target引數是可以省略的。

one方法:

與on方法基本一致,差別是註冊的handler執行過之後就自動remove,也就是說只響應一次事件。

trigger方法

觸發事件,需要給出需要觸發事件的名稱,後面是傳遞給handler的引數。

fire方法

已經廢棄,被trigger方法取代了。

off方法

從事件的監聽者中去掉target+method對應的處理者。target引數是可以省略的。

has方法

獲取指定的事件是否存在監聽者。

五、對標準物件的擴充套件

ember.js對javascript的執行環境做了很多補充,我們簡單看一下。

> 對string的擴充

定義

Ember.String = {

  fmt: function(str, formats) {
    // first, replace any ORDERED replacements.
    var idx  = 0; // the current index for non-numerical replacements
    return str.replace(
/%@([0-9]+)?/g, function(s, argIndex) {
      argIndex = (argIndex) ? parseInt(argIndex,0) - 1 : idx++ ;
      s = formats[argIndex];
      return ((s === null) ? '(null)' : (s === undefined) ? '' : s).toString();
    }) ;
  },

  loc: function(str, formats) {
    str = Ember.STRINGS[str] || str;
    return Ember.String.fmt(str, formats) ;
  },

w: function(str) { return str.split(/\s+/); },

  decamelize: function(str) {
    return str.replace(STRING_DECAMELIZE_REGEXP, '$1_$2').toLowerCase();
  },

相關推薦

ember.js提供基礎服務介紹

write by yinmingjun,引用請註明。 ember.js作為一個全功能的javascript的MVC框架,需要維護大量的程式碼,基於write less use more的原則,ember.js不可避免的抽象了大量的基礎服務,以便最大程度的複用

js基礎知識介紹

pro 知識 bsp var 字符 文本 運算符 span 取余 //js大小寫敏感 註意 ‘‘和; //單行註釋 /*多行註釋*/ //js輸出語法 //alert(‘周天‘); //c

Vue.js基礎學習筆記(一、二章Vue介紹

作為一個iOS開發從業者,前段時間因為公司的需求剛剛學習並開發完成一個屬於前端開發工程師的任務-微信小程式(因為公司規模較小,人員配置不完全,十分無奈),深有感慨。對於移動端原生開發的iOS,Android的雙端開發,中小型公司為了節約開發成本,必然青睞於跨平臺

webAPP專案基礎知識介紹用html5+css3+js開發

最近關於webAPP很火,差不多很多公司開始製作自己的webAPP啦。一談到webAPP,大家就會想到用html5+CSS+js來實現。到底如何來製作?25學堂小編還沒有找到比較合適的用html5+css3開發webAPP專案教材。 這裡分享了一個《網易微博Web Ap

終於搞定使用node.js +redis 作為服務端,提供圖片上傳儲存服務

系統不提供業務層面上的邏輯,只負責儲存和結構關係。業務相關的資料,全部通過引數化傳入。 upload.js 檔案程式碼: //自定義引數區 var basePath='e:/';//上傳的根路徑 var tempPath='c:/'; var redis_ip='127.0

[JS] javascript基礎語法

原因 方法 間接 war init err ring tag 是否 1.javascript是什麽   js是具有面向對象能力的,解釋性的程序設計語言. 2.js的類型   [基本類型]:string number boolean   [復合類型]:對象(對象,函數,數

JS入門基礎(if else 與 switch case / node安裝)

json health 案例 js文件 動作 require 步驟 *** 命令 在 JavaScript 中,為不同的決定來執行不同的動作,我們可使用以下條件語句: if 語句 - 只有當指定條件為 true 時,使用該語句來執行代碼 if...else 語句 - 當條

Centos7下配置phpMyAdmin(提供HTTPS服務)

phpmyadmin https httpd Centos7下配置phpMyAdmin(提供HTTPS服務)phpMyAdmin可以通過web方式控制和操作MySQL數據庫。通過phpMyAdmin 可以完全對數據庫進行操作,例如建立、復制和刪除數據等等。配置環境Centos7 2臺(IP1:19

js程序基礎字符串具體

ring rep ast ascii data- 一個 size per 搜索 1. .charAt()裏面寫數字 在一般瀏覽器上相當於方括號 可是由於IE6的存在他就有了用處 由於IE6不兼容方括號 2. charCodeAt() 和char

Python基礎---Python介紹

python介紹 python基礎 python應用領域 python的創始人為吉多·範羅蘇姆(Guido van Rossum)。1989年的聖誕節期間,吉多·範羅蘇姆為了在阿姆斯特丹打發時間,決心開發一個新的腳本解釋程序,作為ABC語言的一種繼承。 2017年最新的TIOBE排行榜,Py

Linux基礎服務_DNS原理以及正反向DNS配置

應用程序 服務器 dns基礎 DNS服務的原理介紹: dns(Domain Name Service,域名解析服務) 為c/s架構的服務 通常默認的監聽的端口為:53/tcp 53/udp 將dns服務實現的應用程序為:bind

arcgis server10.2.2公布地圖基礎服務的詳細步驟

打開 rgb cor ack target images targe .cn logs 1.直接打開制作好的.mxd文檔,比方這裏: 2.打開mxd文檔之後。打開菜單:file-share as -services 彈出地圖公布服務的界面:

Node.js, Express的服務器搭建過程的問題

節點 順序 post 模塊化 回調地獄 模塊 調試 cheerio void Node.js, Express的服務器搭建過程的問題 Express : node.js 的框架,根據2012年BYvoid的說法,是node.js官方唯一推薦的框架 怎麽搭建項目? - 安

node.js基礎詳細教程(4):node.js事件機制、node異步IO操作

nod server nbsp node i++ 兩個 con 錯誤 定時器 第四章 建議學習時間3小時 課程共10章 學習方式:詳細閱讀,並手動實現相關代碼 學習目標:此教程將教會大家 安裝Node、搭建服務器、express、mysql、mongodb、編寫後臺業務邏

js基礎第二天(代碼調試)

變量 三元 頁面 png 則表達式 調試工具 問題 監視 ima 今天沒有整理太多的知識,今天練習的案例比較多。今天有整理三元表達式。和if判斷更新在了一期,還有關系js代碼的調試 上午幫朋友做了一個效果,真的是感覺自己進步了很多,之前看到讓我幫忙做東西我都是心驚膽戰的,就

node.js基礎詳細教程(5):express 、 路由

講解 打開 .com json -1 mod 設置圖 後臺 var 第五章 建議學習時間4小時 課程共10章 學習方式:詳細閱讀,並手動實現相關代碼 學習目標:此教程將教會大家 安裝Node、搭建服務器、express、mysql、mongodb、編寫後臺業務邏輯、編

node.js基礎詳細教程(6):mongodb數據庫操作

insert lte 數組 執行 cmd命令行 tables 頁面 down 切換 第六章 建議學習時間4小時 課程共10章 學習方式:詳細閱讀,並手動實現相關代碼 學習目標:此教程將教會大家 安裝Node、搭建服務器、express、mysql、mongodb、編寫

node.js基礎詳細教程(7):node.js操作mongodb,及操作方法的封裝

font 裏的 ges 格式 上進 ins 方法 回調函數 方式 第七章 建議學習時間4小時 課程共10章 學習方式:詳細閱讀,並手動實現相關代碼 學習目標:此教程將教會大家 安裝Node、搭建服務器、express、mysql、mongodb、編寫後臺業務邏輯、編寫接口

js學習——基礎知識

data undefined () defined ogl 即使 所有 全局 fine JavaScript //這是註釋 a = 1;//簡單賦值語句 數據類型 js有動態

RestFul服務介紹--JEESZ

restful分布式服務 redis分布式緩存技術 apache shiro spring mvc 1. REST介紹REpresentational State Transfer (REST) 是一種架構原則,其中將 web 服務視為資源,可以由其 URL 唯一標識。RESTful Web