有朋友提出一看來是懵逼的,根本不知道什么是面向UI編程的思想,下面是我之前寫的博客,描述的這中思想,下面為地址,參考下就明了很多了。

1. 前端思想實(shí)現(xiàn):面向UI編程       

2. 面向UI編程框架:ui.js框架思路詳細(xì)設(shè)計(jì)

     

  時(shí)隔第一次被UI思路激勵(lì),到現(xiàn)在1.0的粗糙版本發(fā)布,掐指一算整整半年了。半年之間,有些細(xì)節(jié)不斷推翻重做,再推翻再重做。時(shí)隔今日,終于能先出來個(gè)東西了,這個(gè)版本很粗糙,主體功能大概能實(shí)現(xiàn)了,但是還是有很多很多的問題。不過有問題沒事,可以進(jìn)行修改完善,這是相對(duì)輕松的問題,最艱難的從無到有的創(chuàng)造才是最艱難的。好了,不廢話了,我們直接進(jìn)入正題 --- UI.js功能介紹。

 

首先介紹幾個(gè)概念

  • 分布式:原來的概念只有分布式計(jì)算,它研究如何把一個(gè)需要非常巨大的計(jì)算能力才能解決的問題分成許多小的部分,然后把這些部分分配給許多計(jì)算機(jī)進(jìn)行處理,最后把這些計(jì)算結(jié)果綜合起來得到最終的結(jié)果。這邊要實(shí)現(xiàn)的概念是,

  • 分布式協(xié)作開發(fā)就是將一個(gè)項(xiàng)目分拆多個(gè)組件,可從不同的服務(wù)器上拉取,分布協(xié)作開發(fā)

  • 容器容器用來包裝或裝載物品的貯存器,從web角度來講,web容器是應(yīng)用服務(wù)器中位于組件和平臺(tái)之間的接口集合。

  • 組件供裝配整臺(tái)機(jī)器、構(gòu)件或元件的零件組合或者在電子或機(jī)械設(shè)備中組裝在一起形成一個(gè)功能單元的一組元件,我們這里討論的組件是由html+js+css乃至其他資源組合,完善的能夠?qū)崿F(xiàn)一個(gè)功能且能重復(fù)使用的組合元件。

  • 配置管理:提供一套基礎(chǔ)機(jī)制,通過配置文件修改,來進(jìn)行對(duì)項(xiàng)目的管理

  • 統(tǒng)一管理和注入:本框架中將項(xiàng)目中所有的接口進(jìn)行統(tǒng)一配置和管理,包括組件所需組件的配置和注入。

 

首先為推薦的項(xiàng)目布局:

  app                   ---存放容器的目錄

  component           ---存放組件的目錄

    testCom            ---組件名稱目錄

      css             ---組件樣式

      img           ---組件使用圖片

      js             ---組件使用的腳本

      tpl            ---組件的html標(biāo)簽

      description.txt      ---組件的描述說明

  rely              ---存放ui.js和ui.config文件的目錄

  resources           ---存放靜態(tài)資源的目錄

    css             ---全局使用樣式庫

    img            ---全局使用的圖片庫

    lib              ---第三方引動(dòng)庫

圖片:

photoshop培訓(xùn),電腦培訓(xùn),電腦維修培訓(xùn),移動(dòng)軟件開發(fā)培訓(xùn),網(wǎng)站設(shè)計(jì)培訓(xùn),網(wǎng)站建設(shè)培訓(xùn)

 

結(jié)構(gòu)布局的思想主要使用的分類和拆分思想

  • 將類似結(jié)構(gòu)的構(gòu)造進(jìn)行分離歸納,這樣對(duì)于每個(gè)布局的查找和分布都很好

  • 將組件和容器分開來,是為了防止高耦合,改動(dòng)容器和組件,不會(huì)對(duì)頁面其他布局和組件影響

 

配置文件如下:

photoshop培訓(xùn),電腦培訓(xùn),電腦維修培訓(xùn),移動(dòng)軟件開發(fā)培訓(xùn),網(wǎng)站設(shè)計(jì)培訓(xùn),網(wǎng)站建設(shè)培訓(xùn)

ui.config({    //注入頁面容器    container:{        //名稱:容器地址+是否裝載(PS:如果都為true只會(huì)選擇第一個(gè)模板容器)
        "layout1":["app/demoPage1.tpl",true],        "layout2":["app/demoPage2.tpl",false]
    },    //注入接口    interface:{        "interface1":"www.123.com/interface1111111",        "interface2":"www.123.com/interface2",        "interface3":"www.123.com/interface3",        "interface4":"www.123.com/interface4",        "interface5":"www.123.com/interface555555555555",
    },    //注入組件    component:{        //組件名:組件模板+組件樣式+組件腳本+接口注入+組件是否裝載   ===>  該處可優(yōu)化針對(duì)本地項(xiàng)目和分布式開發(fā)進(jìn)行優(yōu)化
        "test":["component/test/tpl/test.tpl","component/test/css/test.css","component/test/js/test.js",["interface1","interface2"],true],        "test1":["component/test1/tpl/test1.tpl","component/test1/css/test1.css","component/test1/js/test1.js",["interface5","interface2"],true],        "test2":["component/test2/tpl/test2.tpl","component/test2/css/test2.css","component/test2/js/test2.js",["interface1","interface2"],true],        "test3":["component/test3/tpl/test3.tpl","component/test3/css/test3.css","component/test3/js/test3.js",["interface1","interface2"],true],        "test4":["component/test4/tpl/test4.tpl","component/test4/css/test4.css","component/test4/js/test4.js",["interface1","interface2"],true],        "test5":["component/test5/tpl/test5.tpl","component/test5/css/test5.css","component/test5/js/test5.js",["interface1","interface2"],true]
    },    //容器組件映射關(guān)系   選擇的容器名稱:{"頁面容器":"所加載的組件"}    con_com:{
        layout1:{
            con1:"test",
            con2:"test1",
            con3:"test2",
            con4:"test3",
            con5:"test4",
            con6:"test5",
        },
        layout2:{
            con1:"test",
            con2:"test",
            con3:"test",
            con4:"test",
            con5:"test",
            con6:"test",
        }
    }
});

photoshop培訓(xùn),電腦培訓(xùn),電腦維修培訓(xùn),移動(dòng)軟件開發(fā)培訓(xùn),網(wǎng)站設(shè)計(jì)培訓(xùn),網(wǎng)站建設(shè)培訓(xùn)

針對(duì)配置文件的解釋:

1. container

  為頁面布局容器,該tpl模板中全部為ui設(shè)計(jì)好的容器,框架加載的時(shí)候首先會(huì)去查找開發(fā)者設(shè)置使用的哪一種布局,然后解析模板中的容器。該容器是為了整個(gè)頁面換布局設(shè)計(jì)的。如果整個(gè)網(wǎng)站需要轉(zhuǎn)換頁面布局,傳統(tǒng)的做法就是重新設(shè)計(jì)重新編碼,然后搞完了重新部署。而該框架的設(shè)計(jì)思路,就是你重新設(shè)計(jì)一套布局容器,然后在該注入選項(xiàng)中注入你的新的布局容器,然后重新配置新的容器和適配組件的綁定關(guān)系,然后就會(huì)自動(dòng)加載新的布局。

  代碼實(shí)例(全部使用ui-con的值來設(shè)置容器名稱):

photoshop培訓(xùn),電腦培訓(xùn),電腦維修培訓(xùn),移動(dòng)軟件開發(fā)培訓(xùn),網(wǎng)站設(shè)計(jì)培訓(xùn),網(wǎng)站建設(shè)培訓(xùn)

<div style="" ui-con="con1"></div>
<div style="" ui-con="con2"></div>
<div style="margin:0 auto;width:1000px;padding:0;border:0;">
    <div style="display: inline-block;width: 755px;" ui-con="con3"></div>
    <div style="display: inline-block;vertical-align: top;width:200px;padding:10px;" ui-con="con4"></div>
</div>
<div style="" ui-con="con5"></div>
<div style="" ui-con="con6"></div>

photoshop培訓(xùn),電腦培訓(xùn),電腦維修培訓(xùn),移動(dòng)軟件開發(fā)培訓(xùn),網(wǎng)站設(shè)計(jì)培訓(xùn),網(wǎng)站建設(shè)培訓(xùn)

 

2. interface

  該項(xiàng)為了全局統(tǒng)一管理接口。因?yàn)閭鹘y(tǒng)的頁面開發(fā)中,如果一個(gè)接口換了,整個(gè)項(xiàng)目中所有用到該接口的ajax等各種請(qǐng)求都必須一個(gè)一個(gè)的換,所以該處將所有的接口提取出來,做一個(gè)全局管理。并且只要組件所需解口進(jìn)行了注入配置,開發(fā)者只需要在每個(gè)組件的js中在use的第一個(gè)data參數(shù)中就可以拿到該接口地址。

  組件注入接口實(shí)例(data中會(huì)有注入的接口地址):

photoshop培訓(xùn),電腦培訓(xùn),電腦維修培訓(xùn),移動(dòng)軟件開發(fā)培訓(xùn),網(wǎng)站設(shè)計(jì)培訓(xùn),網(wǎng)站建設(shè)培訓(xùn)

use(function(data,that){    var tempObj ={        //reader為一些初始化需要的操作,有時(shí)候會(huì)有注冊事件等,或者一些預(yù)操作,該方法加載完成后會(huì)直接跑起來
        reader:function(){
            that = this;
            that.firm.testLoad();
        },        //注入所有的選擇器,方便選擇器變化,直接修改該對(duì)象中的選擇器,而不需要全局去更改        selector:{
            testBtn:"#testBtn",  //按鈕        },        //注入page中所有的事件,統(tǒng)一管理,建議命名規(guī)范:事件_命名,例 click_login        registerEle:{
        },        //注入所有ajax請(qǐng)求,頁面所有請(qǐng)求,將在這里統(tǒng)一管理,建議命名規(guī)范:ajax_命名,例 ajax_login        ajaxRequest:{
        },        //處理所有回調(diào)函數(shù),針對(duì)一個(gè)請(qǐng)求,處理一個(gè)回調(diào)        callback:{
        },        //臨時(shí)緩存存放區(qū)域,僅針對(duì)本頁面,如果跨頁面請(qǐng)存放cookie或者localstorage等
        //主要解決有時(shí)候會(huì)使用頁面控件display來緩存當(dāng)前頁面的一些數(shù)據(jù)        temp:{
        },        /*
         * 業(yè)務(wù)使用區(qū)域,針對(duì)每個(gè)特別的業(yè)務(wù)去串上面所有的一個(gè)個(gè)原子
         *   因?yàn)樯厦嫠械姆椒ǎ皇亲鲆患?,這邊可以根據(jù)業(yè)務(wù)進(jìn)行串服務(wù),很簡單的
         * */
        firm:{
            testLoad:function(){
                console.log("獲取接口的值:"+data.interface.interface1)
            }
        }
    };
    ui.component.reader(tempObj);
});

photoshop培訓(xùn),電腦培訓(xùn),電腦維修培訓(xùn),移動(dòng)軟件開發(fā)培訓(xùn),網(wǎng)站設(shè)計(jì)培訓(xùn),網(wǎng)站建設(shè)培訓(xùn)

3. component

  注入的所有組件。該組件有2中形態(tài)。針對(duì)本項(xiàng)目(待優(yōu)化中)和針對(duì)分布式開發(fā)項(xiàng)目。該組件的配置為:組件模板+組件樣式+組件腳本+接口注入+組件是否裝載。配置好了這5個(gè)參數(shù)之后,框架會(huì)針對(duì)配置文件,進(jìn)行是否裝載,接口注入,和組件裝載,該方式已經(jīng)實(shí)現(xiàn)。如果作為本地項(xiàng)目的話,可以配置更精簡一點(diǎn),只要格式按照我的布局文件寫,可以直接配置一個(gè)組件的根目錄就好了,就會(huì)自動(dòng)尋找,不過該設(shè)計(jì)待優(yōu)化中,還沒有做好。這塊加載組件模板用的技術(shù)就是ajax技術(shù),css和script用的動(dòng)態(tài)標(biāo)簽。所以如果做分布式,請(qǐng)求組件的時(shí)候,就必須做跨域處理了,這邊就不詳細(xì)描述,如果該組件做的功能請(qǐng)求的接口也支持跨域,那么這個(gè)功能就在其他項(xiàng)目中就可以實(shí)現(xiàn)了,做到了真正的分布式協(xié)作開發(fā)了,而本項(xiàng)目就是作為一個(gè)流量入口,接入互聯(lián)網(wǎng)上所有分布式開發(fā)的資源了

4. con_com

  該配置文件為容器-組件綁定關(guān)系,為你每個(gè)注入的容器配置所需要加載的組件,該項(xiàng)可以根據(jù)容器進(jìn)行配置,也必須配置。如果所配置的組件,在組件配置文件中未注入,框架不會(huì)直接停止解析,而是會(huì)在控制臺(tái)拋錯(cuò),告訴你該組件配置的問題,然后繼續(xù)加載其他正確的容器-組件映射正確的模塊功能,詳細(xì)配置見配置文件。

 

ui.js框架核心代碼粗略解析

  1. 代碼結(jié)構(gòu)使用,因?yàn)樵谝粋€(gè)核心的代碼中肯定會(huì)遇到封裝很多的工具,比如dom操作,一般的tool,ajax等工具。我的選擇結(jié)構(gòu)就是將所有的工具,以參數(shù)的形式注入到匿名函數(shù)中,然后匿名函數(shù)執(zhí)行的就是ui.js的核心功能。代碼結(jié)構(gòu)如下:

photoshop培訓(xùn),電腦培訓(xùn),電腦維修培訓(xùn),移動(dòng)軟件開發(fā)培訓(xùn),網(wǎng)站設(shè)計(jì)培訓(xùn),網(wǎng)站建設(shè)培訓(xùn)

(function(window,document,rely){    //rely就是注入的所有使用的工具,修改起來相對(duì)輕松,核心中使用這些工具,不需要在乎這些方法怎么實(shí)現(xiàn),只需要知道這些方法會(huì)達(dá)成我的目的就好了})(window,document,(function(){    var tool={};    var ajax={};    return {
        tool=tool,
        ajax=ajax
    }
})());

photoshop培訓(xùn),電腦培訓(xùn),電腦維修培訓(xùn),移動(dòng)軟件開發(fā)培訓(xùn),網(wǎng)站設(shè)計(jì)培訓(xùn),網(wǎng)站建設(shè)培訓(xùn)

 

2.  ui.config為入口進(jìn)行配置文件的解析

photoshop培訓(xùn),電腦培訓(xùn),電腦維修培訓(xùn),移動(dòng)軟件開發(fā)培訓(xùn),網(wǎng)站設(shè)計(jì)培訓(xùn),網(wǎng)站建設(shè)培訓(xùn)

/*
    *   內(nèi)部使用一些快捷標(biāo)識(shí)符
    *       0. _  代表dom操作
    *       1. $  代表全局注入的工具類
    *       2. $1 代表注入的ajax類庫
    *       3. $2 代表模板處理類庫
    *       4. $3 代表所有錯(cuò)誤處理信息
    *
    *
    * */

    var _ = relyObj.dom,$ = relyObj.tool,$1 = relyObj.ajax,$2 = relyObj.template,$3 =relyObj.errMsg,$4 =relyObj.htmlModule,that={},ui,UI_global;
    ui = UI_global = {        //對(duì)所有參數(shù)進(jìn)行處理
        config:function(configObject){            //  1. 初始化數(shù)據(jù)池            ui.dataPool.initPool();            if(configObject === undefined){                throw new Error($3.gloErr.noConfig);
            };            //  2. 將配置文件存儲(chǔ)到數(shù)據(jù)池中,做備用
            ui.dataPool.setData_glo("config",configObject);            //  3. 檢查加載頁面容器,加載到body中
            $.each(configObject.container,function(value,key){                if(value[1] === true){
                    ui.dataPool.setData_glo("private",{"pageConName":key});
                    ui.container.loadContainer(key,value[0],function(data){
                        _("body").html(data);
                        dealWithCom();                        return;
                    });
                }
            });            //處理組件方法
            var dealWithCom = function(){                //  4. 處理配置容器和組件映射關(guān)系,取得所有容器所要加載組件的信息
                var temp = ui.dataPool.getData_glo("private","pageConName");                //取得配置文件中關(guān)于當(dāng)前容器中的容器-組件對(duì)應(yīng)關(guān)系
                var tempS = ui.dataPool.getData_glo("config","con_com",temp);                //  5. 判斷組件是否存在,存在即加載組件
                $.each(tempS,function(value,key){                    //判斷組件是否配置
                    var getComInfo = ui.component.isExist_com(value);                    if(getComInfo){                        if (getComInfo[4]){
                            ui.component.loadComponent(value,getComInfo[0]);
                        }else {                            var height =  _("[ui-con='"+key+"']").css("height");
                            _("[ui-con='"+key+"']").html($4.loadErr("line-height:"+height));
                        }

                    }else {
                        console.log($3.component.comConfig(value));
                    }
                });
            };
        },

photoshop培訓(xùn),電腦培訓(xùn),電腦維修培訓(xùn),移動(dòng)軟件開發(fā)培訓(xùn),網(wǎng)站設(shè)計(jì)培訓(xùn),網(wǎng)站建設(shè)培訓(xùn)

3.  數(shù)據(jù)中轉(zhuǎn)池的核心(以對(duì)象方式存數(shù)數(shù)據(jù),而不是數(shù)組,因?yàn)閿?shù)據(jù)需要遍歷,增加很多壓力),這個(gè)是最重要的,因?yàn)檎麄€(gè)框架所依賴的數(shù)據(jù)處理都在這里面,它還沒有很完善一些細(xì)節(jié)還是需要推敲的,比如說以后拒絕開發(fā)者修改一些內(nèi)部使用中的數(shù)據(jù),因?yàn)檫@些數(shù)據(jù)是框架內(nèi)部處理使用,而非外部,修改不當(dāng)容易造成整體崩潰。它規(guī)定一些重要的參數(shù),以及向數(shù)據(jù)池增加參數(shù)和得到數(shù)據(jù)池的參數(shù)的方法和規(guī)定

photoshop培訓(xùn),電腦培訓(xùn),電腦維修培訓(xùn),移動(dòng)軟件開發(fā)培訓(xùn),網(wǎng)站設(shè)計(jì)培訓(xùn),網(wǎng)站建設(shè)培訓(xùn)

/*
        *   數(shù)據(jù)中轉(zhuǎn)池核心處理庫(以對(duì)象方式去存儲(chǔ),這樣方便快捷的取數(shù)據(jù))
        *       數(shù)據(jù)格式:
        *           1. mapping(name + uuid )映射,每個(gè)name對(duì)應(yīng)一個(gè)uuid  注:每加載一個(gè)頁面容器生成一個(gè)uuid,每次加載一個(gè)組件,生成一個(gè)組件的uuid,盡量,按需創(chuàng)建和使用
        *           2. pool(uuid + data )映射,每個(gè)uuid對(duì)應(yīng)儲(chǔ)存一段數(shù)據(jù)
        *               a. interface,注入接口信息
        *               b. transfer,流轉(zhuǎn)過來的數(shù)據(jù)
        *           3. pageContainer,存儲(chǔ)當(dāng)前加載的頁面中所有的頁面容器
        *           4. global_temp,全局存儲(chǔ)的臨時(shí)數(shù)據(jù)
        *           5. config,存儲(chǔ)用戶配置的參數(shù)
        *           6. private,存儲(chǔ)UI.js本身處理過的數(shù)據(jù),內(nèi)部使用   (需要加載的組件)
        *
        * */
        dataPool:{            //初始化數(shù)據(jù)池,將數(shù)據(jù)池都清空
            initPool:function(){
                that["dataCenter"]={
                    mapping:{},                 //數(shù)據(jù)例子: "module":"ffb71d7f-995b-4898-8e4b-b283a4fe6253"
                    pool:{},                    //數(shù)據(jù)例子:"ffb71d7f-995b-4898-8e4b-b283a4fe6253":{索要存的對(duì)象}
                    pageContainer:{},           //數(shù)據(jù)例子:"name":"http://xxxxx.com"
                    global_temp:{},             //數(shù)據(jù)例子:"Test":"123321"      做全局緩存用
                    config:{},                  //數(shù)據(jù)例子:值為config中的配置參數(shù)值
                    private:{}                 //數(shù)據(jù)例子:內(nèi)部使用參數(shù),處理ui.js的內(nèi)部流程                };
            },            //檢查是否為數(shù)據(jù)池全局拒絕修改的參數(shù) (待定)
            checkParam_glo:function(name){                var data =["interface","config","private"],len = data.length;                while(len--> 0){                    if(name === data[len]){                        throw new Error($3.pool.forbidUpdate(name));
                    }
                }                return true;
            },            /*
            *   數(shù)據(jù)池設(shè)置數(shù)據(jù)池全局的值(該方法為了固定數(shù)據(jù)池的參數(shù),防止數(shù)據(jù)錯(cuò)亂)
      http://www.cnblogs.com/GerryOfZhong/p/6383175.html