2017年5月28日 星期日

安裝 (React 16 一)

寫這篇時,官網的版本是15.5.4
本來是0.14,後面直接升級到15,現在最新是16,原文件
官網文件中文文件


※安裝

可以下載 js 使用,也可以使用 Node.js

React Developer Tools:chrome 到這裡下載,如果執行的是 react,按 F12 會有 React的活頁標籤,但我試的時候,使用 Node.js 執行沒有問題;但使用下載 js 的方式,按下活頁標籤會出現「Uncaught TypeError: Cannot read property 'nativeObjectCreate' of undefined」的警告

.原本執行 react 時,沒出現警告,但一按 React 活頁標籤出現警告時,連原本的也會出現警告,並不是 react 寫錯了,重新整理沒有用,必需將此 js 關掉,重開即可
反正使用下載 js 的方式就不要用 React Developer Tools

※下載 js

使用 BootCDN,下載四個東西
.react:react 的核心庫
https://cdn.bootcss.com/react/16.3.2/umd/react.development.js

.react-dom:操作 dom
https://cdn.bootcss.com/react-dom/16.3.2/umd/react-dom.development.js

.babel-standalone:使用 JSX
https://cdn.bootcss.com/babel-standalone/7.0.0-beta.3/babel.js

.prop-types:可以為欄位定義型態、是否必輸,不是強制的,但 console 會有警告
https://cdn.bootcss.com/prop-types/15.6.1/prop-types.js

複製網址到新開的頁面,然後整個複製成一份新文件
也可用官網安裝教學的 CDN Links,但必需上網才能使用,或者學 BootCDN 的做法,複製下來也是可以,但只有看到 react 和 react dom



<script src="../js/react.development_16.3.2.js"></script>
<script src="../js/react-dom.development_16.3.2.js"></script>
<script src="../js/babel-standalone_7.0.0-beta.3.js"></script>
<script src="../js/prop-types._15.6.1.js"></script>
    
<div id="div1"></div>
<div id="div2"></div>
<div id="div3"></div>
    
<script type="text/babel">
    const dom1 = React.createElement('h1', '', 'aaa')
    ReactDOM.render(
        dom1, document.querySelector("#div1")
    );
    
    ReactDOM.render(
        <h1>bbb</h1>, document.querySelector("#div2")
    );
    
    const dom3 = <h1>ccc</h1>;
    ReactDOM.render(
        dom3, document.querySelector("#div3")
    );
</script>

※要注意下語法的 script 是 babel,不是 javascript

※以上三種方法都可以,但要小心第二和第三種方法,不能用「'」或「"」包起來

※createElement 參數依序為標籤名、標籤的屬性、內容

※jsx 的根標籤必需只有一個,如上只有一個 h1,如果有很多個 h1,那就不行,解法可在 h1上面加個根標籤,如 div 之類的

※使用自訂標籤

class Dom1 extends React.Component {
    render() {
        return <h1>aaa</h1>
    }
}
    
const Dom2 = _ => {
    return <h1>bbb</h1>
}
    
ReactDOM.render(
    <Dom2 />, document.querySelector("#div1")
);

※有兩種方法,注意一定要大寫開頭

※render 的第一個參數也是用標籤



※使用 Node.js

安裝好 Node.js 後,如下操作
1.npm install -g create-react-app:安裝 create-react-app 指令
2.create-react-app 專案名稱:新增一個專案
3.進入新專案,內容如下(src backup 是我加的):

4.下 npm start:下完會自動跳出瀏覽器 localhost:3000

改port:package.json,scripts有個start
原本是 react-scripts start,改成set PORT=9000 && react-scripts start,如下:


使用 Node.js 的方式,必需將 react 和 html分開

public 的 index.html 寫 html
src 的 index.js 寫react 語法
package.json 設定可參考這裡這裡

※src\index.js

import React from 'react';
import ReactDOM from 'react-dom';
    
ReactDOM.render(<h1>Yeah</h1>, document.querySelector("#d1"))

※雖然已經 import,但 ReactDOM 還是要寫

※public\index.html 內容就不貼了,反正一定要有個 id 是 d1 即可

※如果要使用其他組件,如下面 App.js (放在和 index.js 同層) 的語法
import React, { Component } from 'react';
    
class Xxx extends React.Component {
    render() {
        return <h1}>xxx</h1>
    }
}
    
export default Xxx;

※React.Component 可以只寫 Component

※匯出名稱是 Btn


import React from 'react';
import ReactDOM from 'react-dom';
import Xxx from './App';
    
ReactDOM.render(<Xxx />, document.querySelector("#d1"))

※引用時也是用 Btn,但 from 是寫 App 的路徑

2017年5月24日 星期三

Ext.define (ExtJS 4 二)

以下為了方便,就不貼Ext.onReady了
文件要在 Ext (最上面) 點一下即可
Ext.define 是定義類別的(最後沒有d),可以使用 Ext.create 和 new 的方式使用這個類


※一、使用Ext.create

Ext.define("xxx.ooo", { 
    aaa : "a1",
    bbb : "b1",
    ccc : function(){
        return this.aaa + " " + this.bbb;
    }
});
    
var a = Ext.create("xxx.ooo");
Ext.Msg.alert("標題", "我是" + a.aaa, function(){
    // var a = Ext.create("xxx.ooo"); 不能寫在裡面
    Ext.Msg.alert("call back 標題", a.ccc());
});




※覆蓋

Ext.define("xxx.ooo", { 
    aaa : "a1",
    bbb : "b1"
});
    
Ext.define("xxx.ooo", { 
    aaa : "a2"
});
    
var obj = new xxx.ooo();
alert(obj.aaa); // a2
alert(obj.bbb); // undefined

※因為後者蓋前者,所以 obj.bbb 就沒有了


※setter/getter (config)

Ext.define("xxx.ooo", {
    config : {
        ddd : 'abc',
        eee : 'def'
    }
});
    
var a = Ext.create("xxx.ooo");
    
alert(a.getDdd()); // abc
a.setDdd('aaa');
alert(a.getDdd()); // aaa

※使用內鍵的 config 就可以做到 setter/getter



※二、使用new

Ext.define("xxx.ooo", { 
    aaa : "a1",
    bbb : "b1"
});
    
var obj = new xxx.ooo();
alert(obj.message); // undefined
obj.message = 'msg';
alert(obj.message); // msg
alert(obj.aaa); // a1



※繼承 (extend)

Ext.define("xxx.ooo", { 
    aaa : "a1",
    bbb : "b1"
});
    
Ext.define("xxx.ooo.qqq", { 
    extend: 'xxx.ooo' // 最後沒有「s」,最後也不可加「;」
});
    
var obj = new xxx.ooo.qqq();
alert(obj.aaa); // a1
alert(new xxx.ooo.qqq().bbb); // b1

※使用內鍵的 extend 可以做到繼承

※因為繼承的關係,所以 aaa 和 bbb 還是有值


※靜態屬性、靜態方法 (statics、inheritableStatics)

Ext.define("xxx.ooo", { 
    aaa : "a1",
    statics : { // statics,後面有「s」
        bbb : "b1",
        ccc : function(){
            return 'ccc';
        }
    }, 
    inheritableStatics : {
        ddd : "d1",
        eee : function(){
            return 'eee';
        }
    }
});
    
var obj = new xxx.ooo();
alert(obj.aaa); // a1
alert(xxx.ooo.bbb); // b1
alert(xxx.ooo.ccc()); // ccc
// alert(obj.ccc()); // Uncaught TypeError: obj.ccc is not a function
alert(obj.bbb); // undefined
    
alert(xxx.ooo.ddd); // d1
alert(xxx.ooo.eee()); // eee
// alert(obj.ddd()); // Uncaught TypeError: obj.ddd is not a function
alert(obj.eee); // undefined

※使用內鍵的 statics 和 inheritableStatics 可以做到靜態

※靜態屬性沒有時是 undefined,但靜態方法沒有時會報錯,以下無法執行


※statics 和 inheritableStatics 差異

Ext.define("xxx.ooo", { 
    aaa : "a1",
    statics : { // statics,後面有「s」
        bbb : "b1",
        ccc : function(){
            return 'ccc';
        }
    }, 
    inheritableStatics : {
        ddd : "d1",
        eee : function(){
            return 'eee';
        }
    }
});
    
Ext.define("xxx.ooo.qqq", {
    extend: 'xxx.ooo' //最後不可加「;」
});
    
alert(xxx.ooo.qqq.bbb); // undefined
// alert(xxx.ooo.qqq.ccc()); // Uncaught TypeError: xxx.ooo.qqq.ccc is not a function
    
alert(xxx.ooo.qqq.ddd); // d1
alert(xxx.ooo.qqq.eee()); // eee

※statics 無法被繼承;而inheritableStatics可以


※別名 (alias)

Ext.define("xxx.ooo", {
    aaa : "a1",
    alias : 'xo'
});
    
var a = Ext.create('xo');
alert(a.aaa);
// alert(new xo()); // Uncaught ReferenceError: xo is not defined

※通過關鍵字 alias 即可達成,但只適用在Ext.create


※備用類別名稱 (alternateClassName)

Ext.define("xxx.ooo", {
    aaa : 'a1',
    alternateClassName: ['zzz', 'yyy.zzz']
});
    
alert(new xxx.ooo().aaa); // a1
alert(new zzz().aaa); // a1
alert(new yyy.zzz().aaa); // a1
alert(Ext.create('yyy.zzz').aaa); // a1

※比 alias 好,使用 new 和Ext.create 都可以


※建構子 (constructor)

Ext.define("xxx.ooo", {
    aaa : 'default aaa',
    bbb : 'default bbb',
    constructor : function(aaa) {
        this.aaa = aaa;
    },
    constructor : function(aaa, bbb) {
        this.aaa = aaa;
        this.bbb = bbb;
    }
});
    
var obj1 = new xxx.ooo();
alert(obj1.aaa); // undefined
alert(obj1.bbb); // undefined
    
var obj2 = new xxx.ooo('a');
alert(obj2.aaa); // a
alert(obj2.bbb); // undefined
    
var obj3 = new xxx.ooo('a', 'b');
alert(obj3.aaa); // a
alert(obj3.bbb); // b

※注意沒有參數的建構子,屬性都是 undefined,如果沒有加 constructor,可以得到 default aaa和 default bbb




※還有其他內鍵的,在左邊點 Class 即可看見,有 10 個

HelloWorld、事件 (ExtJS 4 一)

※HelloWorld

下載完後的圖
下載完有200多MB,但其實只要 locale 和 resources 資料夾和所有檔案,只要 27MB 左右

文檔連結
上面圖的上一層是一個叫 extjs-4.1.1a 的資料夾,以下的測試檔就是放在這一層

<html>
    <head>
        <title>ExtJS4 Test</title>
        <script src="extjs-4.1.1a/ext-all.js"></script>
        <script src="extjs-4.1.1a/locale/ext-lang-zh_TW.js"></script>
        <script src="extjs-4.1.1a/locale/ext-lang-zh_CN.js"></script>
        <link href="extjs-4.1.1a/resources/css/ext-all.css" rel="stylesheet" />
    </head>
    
    <script>
        Ext.onReady(function(){
            Ext.Msg.alert('標題', '內容');
        });
    </script>
</html>

※可以發現文檔裡還有很多,如prompt、confirm…等,都在Methods裡,當然還有Properties、Events、Config options

※方法和 Ext.onReady 都會後者蓋前者,不是附加哦!

※Ext.onReady 裡面還可以再放 Ext.onReady,但是內層會覆蓋外層,如下:
Ext.onReady(function(){
    Ext.Msg.alert('標題1', '內容1');
    
    Ext.onReady(function(){
        Ext.Msg.alert('標題2', '內容2');
        
        Ext.onReady(function(){
            Ext.Msg.alert('標題3', '內容3');
        });
    
    });
});

※所以最後都被「標題3,內容3」覆蓋


※文檔有寫「Ext.MessageBox alias Ext.Msg」,所以都是一樣的
或者用 var xxx = new Ext.window.MessageBox; 然後再用「xxx.方法」也是 ok 的

※alert還有第三、四個參數,不是必要的,看文檔



※事件

※單一事件

<html>
    <head>
        <title>ExtJS4 Test</title>
        <script src="extjs-4.1.1a/ext-all.js"></script>
        <script src="extjs-4.1.1a/locale/ext-lang-zh_TW.js"></script>
        <script src="extjs-4.1.1a/locale/ext-lang-zh_CN.js"></script>
        <link href="extjs-4.1.1a/resources/css/ext-all.css" rel="stylesheet" />
    </head>
    
    <script>
        Ext.onReady(function(){
            var btn = Ext.get("b");
            btn.on('click', function(a,b,c){
                alert('好痛');
            });
        });
    </script>
    
    <body>
        <button id="b">按我</button>
    </body>
</html>

※Ext.get 回傳 Ext.dom.Element ,裡面有個 on 方法



※多個事件

<html>
    <head>
        <title>ExtJS4 Test</title>
        <script src="extjs-4.1.1a/ext-all.js"></script>
        <script src="extjs-4.1.1a/locale/ext-lang-zh_TW.js"></script>
        <script src="extjs-4.1.1a/locale/ext-lang-zh_CN.js"></script>
        <link href="extjs-4.1.1a/resources/css/ext-all.css" rel="stylesheet" />
    </head>
    
    <script>
        Ext.onReady(function(){
            var btn = Ext.get("b");
            btn.on({
                'click': {
                    fn : function(evt, el, o){
                        alert('好痛');
                    },
                    scope:this,
                    delay:1000
                },
    
                'mouseout': {
                    fn : function() {
                        alert('好爽');
                    }
                }
            });
        });
    </script>
    
    <body>
        <button id="b">按我</button>
    </body>
</html>