這只是一篇筆記文,所以也沒什麼前言,只有一點要特別注意,forEach是ES5的語法,所以用IE舊版的朋友,祝你好運。
我們就直接開始吧。
var a = [1,2,3,4,5];
a.forEach(function(x){
if (x == 2) return; // continue
if (x == 4) return false; // break
console.log(x)
})
ouput:
1
3
以上
2016年12月9日 星期五
2016年12月8日 星期四
如何只靠html&css輸出A4的畫面
目標
相信大家在做專案的時候不免會遇到一些要輸出報表,或輸出什麼單什麼單的時候。然而通常我們用的技術越簡單,對專案開發速度的提升跟交接的難易度也越低。
而這個方法,真的是小編所能找到最簡單的方法了,過程中只有 Html 跟 CSS ,甚至一行 JS 都不需要有!(範例中那行是方便大家輸出跟觀察,直接把print指令寫好了)這對目前是前端工程師的小編來說,根本是逆天的簡單(當然對各位大大來說也是一樣啦 ),而唯一要做的前置作業,就是去查出你要輸出的紙張的size,必要時再去弄一張版型的圖片,當然圖片大小也要調得一樣,這樣可以方便做細部的調整。
廢話不多說我們就直接開始吧。
Html:
<!DOCTYPE html><html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<div class="book" id="app">
<div class="page">
<div class="subpage">
page1/2
</div>
</div>
<div class="page">
<div class="subpage">
page2/2
</div>
</div>
</div>
</body>
<sciript>widnow.print()</script>
</html>
上網查了一下,A4 size = 210mm*297mm,那我們就開始寫CSS吧
CSS:
body {width: 100%;
height: 100%;
margin: 0;
padding: 0;
background-color: #FAFAFA;
font: 12pt "Tahoma";
}
* {
box-sizing: border-box;
-moz-box-sizing: border-box;
}
.page {
width: 210mm; /*隨著紙張大小異動*/
min-height: 297mm;/*隨著紙張大小異動*/
padding: 20mm;
margin: 10mm auto;
border: 1px #D3D3D3 solid;
border-radius: 5px;
background: white;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
}
.subpage {
padding: 1cm;
border: 5px red solid;
height: 257mm;/*隨著紙張大小異動*/
outline: 2cm #FFEAEA solid;
}
@page {
size: A4;
margin: 0;
}
@media print {
html, body {
width: 210mm;/*隨著紙張大小異動*/
height: 297mm; /*隨著紙張大小異動*/
}
.page {
margin: 0;
border: initial;
border-radius: initial;
width: initial;
min-height: initial;
box-shadow: initial;
background: initial;
page-break-after: always;
}
}
小結
如果有需要,可以直接在page裡面加入 background-image,自行加入要列印單子的版型,這樣可以快速調整到自己想要的位置,甚至可以儲 positon 到資料庫,因應各家不同廠商的單子。光想到就內牛滿面。
小編過足了兩年都過著用 position:releative 去微調每個欄位,然後再列印出來,看到底還差多少,然後硬體不同還會跑版,一整個吐血,無形中不知道浪費了多少紙張,讓北極熊唾棄了幾次,所以後來小編終於受不了良心譴責,離開了那間公司,哈。
不過就這樣短短的程式碼,確實簡單又便利。留起來筆記,也希望可以幫助正在為報表所苦的朋友們,也歡迎大家留言或寄信給我討論
求php攻城屍在面對oracleDB時內心的陰影面積
前言
雖然小編寫php行之有年,而且最近還轉戰前端工程,但我還是沒有放棄php的~~~~(其實只是剛好專案需要)
在完全不知道要怎麼著手,大部分網路神人的教導又沒辦法完全解決問題的時候,真的很苦惱啊.......所以這邊就是我完成了連線並且成功取到資料的一篇筆記,先說小編完全不了解其運作原理,只知道怎麼做到,所以請各位鞭小力一點 = =
經過小編不怕死嘗試,就算library是12c,也一樣可以連線11g的版本
環境設定
所以直接無腦入門了,裝了appserv最新的版本,把php切換到7(appserv裡面有一支PHPVersion Switch可以做到切換,不然預設是跑php5)
(小編因為個人需求所以用appserv會簡單些,如果用習慣xampp或其他的也是可以,可以跑php就好)
切換好PHP版本後,開始修改php.ini,尋找oci,會找到
;extension = php_oci8_12c.dll
;extension = php_pdo_oci.dll
把前面的分號拿掉並儲存
instant client
只靠PHP原生的DLL是無法連線oracl的,需要而外引入dll,所以這時必須上oracle官網載instant client,因為windows的php目前只有32位元版,所以這裡也必須載32位元版,這時看你剛剛修改的php.ini檔內容可以知道你要抓哪個版本的instant client (小編這時是抓12版)。
下載完解壓縮在C:\,會有個資料夾叫 instantclient_12_1,根據網路上的說法,必須把這個資料夾設定在系統環境變數內,並重新啟動電腦。但小編試過,不知道為什麼總是出不來,模組無法讀取,出現錯誤訊息:call undefined function oci_connect()....。最後乾脆把資料夾內的東西全數複製到php\ext & apache\bin兩個資料夾中。然後apache restart就抓到oci_connect function了
(php連線測試程式碼會附在最後)
語系
可以連線後,小編又遇到一個問題,錯誤訊息:
ora-12705: cannot access nls data files or invalid environment specified
上網看資料大概是語系問題吧,這時你必須知道oracle主機上 NLS_LANG 的設定是什麼
根據網友說法,開啟 regedit.exe 找到 HKEY/SOFTWARE/ORACLE 可以看到字串 NLS_LANG值為NA,直接刪掉他就好了
不知道是不是因為作業系統的關係,小編的路徑是HKEY/SOFTWARE/Wow6432Node/ORACLE,如果都找不到,直接ctrl+F找NLS_LANG也可以,小編也是這樣找到的。另外小編的解決方式是填入跟主機樣的的設定。
設定完之後記得重新啟動apache,然後你就會看到你畫面上出現success!
(主機是linux,只要下指令: unset NLS_LANG 似乎就可以解決,或是 set NLS_LANG=xxxxxxxx)
(主機是linux,只要下指令: unset NLS_LANG 似乎就可以解決,或是 set NLS_LANG=xxxxxxxx)
這時你必須取得host、port(預設1521)、SID(或SERVICE NAME、SERVER),當然還有帳號密碼。
因為要填寫connect string,詳細規格看PHP官網或oracle官網就很清楚了
因為要填寫connect string,詳細規格看PHP官網或oracle官網就很清楚了
程式碼如下
<?php
$db = "(DESCRIPTION=
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.xx.xx)(PORT = 1521))
)
(CONNECT_DATA=
(SID=xxxx)
)
)";
$conn = oci_connect("user_id","password",$db);
if(!$conn){
echo "db access error: ";
print_r(oci_error());
exit;
}
else
{
echo "success!";
}
?>
小結
跟網路上許多人隨隨便便就弄上3、5天甚至1、2個禮拜的人來說,小編算花很短的時間了,特別在主機又不是我可以輕易操作的情況下,小編還是活過來了,所以正在為oracle所苦的各位,一定可以撐過來。藉由這次機緣才了解到oracle真的是博大精深阿,據說還有db以外的用法,不過......有機會再來研究拉= =(逃) 還有它真的很貴= =一套破百萬來著,所以各位如果接到用oracle的案子,不要怕,盡量開價吧~~小編我就是沒有做好功課,亂開價嗚嗚~ ><"
另外提個小小的意外,我在取資料時,要輸出json,卻一直無法輸出,原來是json_encode不接受big5格式......所以必須自己寫程式去轉碼。好吧,這種小事情還是自己動手寫一支吧。
<?php
function convertEncoding($data) {
return is_array($data)?
array_map(function($val){
return convertEncoding($val);
}, $data):
mb_convert_encoding($data, "UTF-8", "BIG-5");
}
?>
2016年10月21日 星期五
React入門筆記
必須說小編實在不喜歡React的撰寫方式跟風格,畢竟一開始吃了不少鱉。不過既然我學習過我還是簡易做個筆記吧。
Ps.本篇網誌是有段時間前寫的。
有人會問既然小編不喜歡React,但為什麼還是要學呢?一切都是因為……
網路上工作職缺打開,每個都要React & Angular開發經驗者佳,WTF!! 所以今天你只需要知道,你學會了 = More Money!! 如何~有沒有動力了~
一言以蔽之就是:這是一個前端JS框架。OK~這句話似乎又衍生了更多問題,用在什麼地方?好不好用?優點是什麼?跟Angular比較起來差別是?為什麼我要用?
OK,為什麼我要用?大部分情況下,我們都會有專案期限的壓力,通常在這種壓力下,一般人(小編就是一般人啦)就會選用自己最擅長,最有把握的語言(工具)去完成專案,這有什麼優缺點呢? 優點就是專案如期完成的機率大幅提升。缺點呢? 井底之蛙,你會的永遠就是這些,你的速度永遠這麼慢,且你永遠不知道世界有多大,進步有多快。保哥曾在篇網誌上說過,一個工程師的價值在於它是否願意花時間去縮短他的coding時間。簡單說就是提升工作效率啦。一個網站從到尾自己刻的時代已經過去了,什麼都就講究自動化的今天,資料要越乾淨越好,工程師做的事情要越少越好,所以這些前端框架就應運而生。
比起Angular又如何呢?先說小弟我其實是支持Angular啦,特別是A2已經出到RC版的今天,差不多可以進場了,後面再講資料流的時候我會跟大家提到,不過有時專案需要,我們還是要搞懂React這傢伙在搞什麼。
接下來開始進入React的核心
React並不能算是個完整個框架,官方推出React的時候希望落實關注點分離,讓大家可以專注於View的開發,所以充其量React只是MVC中的View而已(有一點點的M啦),其最重要也是最強大的功能就是Render:宣染 VDOM(虛擬DOM),我敢保證,你看完說明肯定還是不懂我在說什麼,沒關係就直接進我們第一個範例吧
第一支React
1
2
3
4
5
6
7
8
9
10
11
|
HTML:
<div
id="example"></div>
JSX:
ReactDOM.render(
<h1>Hello,
world!</h1>, //將這個物件,丟到下面這個元件之中
document.getElementById('example') //丟到我裡面吧
);
render result:
<div
id="example"><h1>Hello, world!</h1></div>
|
把這些寫在JS代碼中的HTML(VDOM)宣染到畫面上,這就是React最大的賣點,集中撰寫,跟宣染速度快,因為它會透過底層演算,用最小的幅度去修改畫面(不過最近被Vue跟Angular2打臉了),附上一篇文章
對React來說,很重要的一個觀念,你畫面上看到的所有東西都是元件(components)
Component props
1
2
3
4
5
6
7
8
9
10
11
12
13
|
var HelloMessage = React.createClass({
render:
function() {
return <h1>Hello
{this.props.name}</h1>; => 所以這邊會輸出Hello John
}
});
ReactDOM.render(
<HelloMessage
name="John" />, =>設定這物件的name屬性為John
document.getElementById('example')
);
開嗆時間:
angular 這樣寫就好了 <h1
ng-init="name='John'">Hello {{name}}</h1>
|
所以其中一個React很大的優勢就是,可以局部重購,因為可以把畫面拆成許多Components,元件中也可以包元件
在JSX中{}內可以正常的寫JS,若是放入array,也會批次被render出來
Array for React
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
var names =
['Alice', 'Emily', 'Kate'];
ReactDOM.render(
<div>
{
names.map(function
(name) {
return <div>Hello,
{name}!</div>
})
}
</div>,
document.getElementById('example')
);
Demo
開嗆時間:
angular 這樣寫就好了 <div ng-repeat="name in
names">{{name}}</div>
|
Children
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
var Comment =
React.createClass({
render:
function() {
return (
< div className = "comment" >
<
h2 className = "commentAuthor" >
{ this.props.author}
<
/h2>
{this.props.children}
< /div>
);
}
});
var CommentList = React.createClass({
render:
function() {
return (
<
div className = "commentList" >
<
Comment author = "Pete Hunt" > This is one comment
< /Comment>
<
Comment author = "Jordan Walke" > This is * another *
comment < /Comment >
<
/div>
);
}
});
ReactDOM.render(
<CommentList
/>,
document.getElementById('container')
);
/*
這裡可以用children取子節點,如果子節點是很多個物件,那取回來就會是陣列,例如這樣
</Parent>
<ChildrenA
/>
<ChildrenB
/>
<ChildrenC
/>
</Parent>
*/
|
attr 共用屬性
1
2
3
4
5
6
7
8
9
10
11
|
var attr = {}; => 共用的屬性,不想重複打可以這樣做
attr['id'] = "a";
attr['name'] = "b";
attr['class'] = "c";
render(
<input
{...attr} onChange={this.valueChg.bind(this,tr_index,td_index)}/>
) //event如果要綁定參數,必須用bind(this......)的方式呼叫
render result:
<input id="a" name="b" class="c" onChange={this.valueChg.bind(this,tr_index,td_index)}/>
|
event, refs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
var MyComponent =
React.createClass({
handleClick: function() {
this.refs.myTextInput.focus();
},
render: function() {
return (
<div>
<input
type="text" ref="myTextInput"/> // reference參考,在這可以把它當成向指定idㄧ樣指定物件
<input
type="button" value="Focus the text input" onClick={this.handleClick}
/> //onClick觸發handleClick()
</div>
);
}
});
ReactDOM.render(
<MyComponent />,
document.getElementById('example')
);
|
state
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
var LikeButton =
React.createClass({
getInitialState:
function() { =>初始化state
return {liked: false};
=> liked = false;
},
handleClick:
function(event) {
this.setState({liked:
!this.state.liked}); => 設定liked 反向
},
render: function() {
var text
= this.state.liked ? 'like' : 'haven\'t liked';
return (
<p
onClick={this.handleClick}>
You
{text} this. Click to toggle.
</p>
);
}
});
ReactDOM.render(
<LikeButton />,
document.getElementById('example')
);
|
React裡面有個很重要的觀念,state改變,元件就會重新render,所以要想改變畫面上的東西,只有model改變是不夠的,看看以下範例
rerender
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
var Input = React.createClass({
getInitialState:
function() { // 設定初始state
return {value: 'Hello!'};
},
handleChange:
function(event) {
this.setState({value:
event.target.value}); // 若不藉此改變state畫面上的數值是不會更動的,除非是改用defaultValue,但如此便無法掌握資料了
},
render:
function () {
var
value = this.state.value;
return (
<div>
<input
type="text" value={value} onChange={this.handleChange} />
<p>{value}</p>
</div>
);
}
});
ReactDOM.render(<Input/>,
document.getElementById('example'));
開嗆時間:
Angular只要這樣寫
<input type="text" ng-model={value}
/>
<p>{{value}}</p>
|
this.props通常是使用在父元素傳值給子元素的情境上this.props 以及 this.state。這兩個屬性有不同的特性與行為,在使用上,官方建議靜態資料使用this.props,動態資料使用this.state。
value
defaultValue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
var MyComponent = React.createClass({
getInitialState:
function() {
return {a: "a"};
},
handleClick1:
function() {
this.refs.myTextInput1.value="b";
this.refs.myTextInput2.value="b";
},
handleClick2:
function() {
this.setState({a:"b"});
},
change1:
function(e) {
alert(e.target.value)
},
change2:
function(e) {
alert(e.target.value)
},
render: function()
{
return (
<div>
<input
type="text" ref="myTextInput1" defaultValue={this.state.a}
onChange={this.change1}/>
//直沒有被綁定,可以透過onChange偵聽,也可以透過事件改變,但資料不好掌握
<br/> //
因為必須是完整的巢狀式迴圈,所以一定要加上反斜線
<input
type="text" ref="myTextInput2" value={this.state.a}
onChange={this.change2}/>
//值被state.a綁定了,也可以透過onChange偵聽,但值不會更改,但可以被事件改變(不觸發onChange),但這樣它的優勢(資料好掌握)就沒了,一旦資料被rerender,值會再回到state.a
<br/>
<input
type="button" value="changeA" onClick={this.handleClick1}
/>
<br/>
<input
type="button" value="changeState" onClick={this.handleClick2}
/>
</div>
);
}
});
ReactDOM.render(
<MyComponent
/>,
document.getElementById('container')
);
|
className
1
2
3
4
5
6
7
8
9
10
11
|
var HelloMessage =
React.createClass({
render:
function() {
var
classString = "msg";
return <div
className={classString}>Hello, I'll be there</div>; => 其實就是正常html的class,但class這名詞是React的專有名詞,所以不能直接使用
}
});
ReactDOM.render(
<HelloMessage
/>,
document.getElementById('example')
);
|
其實React也可以做到two-way-data-binding
two-way-data-binding
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
var WithLink =
React.createClass({
/* 載入
React.addons.LinkedStateMixin 中的方法 (this.linkState)*/
mixins:
[React.addons.LinkedStateMixin], //應該是類似擴充方法
getInitialState:
function () {
return {message: 'Hello!'}
},
render:
function () {
/*邏輯處理的地方*/
return (
<div>
<input
type='text' valueLink={this.linkState('message')} />
{this.state.message}
</div>
)
}
});
|
但是two-way-data-binding做完可以在render裡面做些簡單的視覺邏輯,但render裡面本來就不適合放資料處理邏輯,所以如果真的要走資料流,也不適合這種方式,這也是這個好用的功能卻一值沒沒無聞的原因。
大致上,元件執行生命週期方法的情形可分為四種
初始化,第一次 render
getDefaultProps()
getInitialState()
componentWillMount()
render()
componentDidMount()
props 發生改變時
componentWillReceiveProps(nextProps)
shouldComponentUpdate(nextProps,
nextState)
componentWillUpdate(nextProps,
nextState)
render() => 我試不出來
componentDidUpdate(prevProps,
prevState)
state 發生改變時
shouldComponentUpdate(nextProps,
nextState)
componentWillUpdate(nextProps,
nextState)
render()
componentDidUpdate(prevProps,
prevState)
元件 unmount 卸載時
componentWillUnmount()
來看個簡單範例
生命週期範例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
var Hello = React.createClass({
getInitialState:
function () {
return {
opacity: 1.0
};
},
componentDidMount:
function () { => 必須在宣染完後才能開始動作
this.timer
= setInterval(function () {
var
opacity = this.state.opacity;
opacity
-= .05;
if (opacity
< 0.1) {
opacity
= 1.0;
}
this.setState({
opacity:
opacity => 變更透明度後重新寫入state,react會自動重新宣染該物件
});
}.bind(this), 100);
=> bind(this)在JSX裡面會常常用到,但這不是JSX特有的寫法,而是JS本身的特性,告訴在這個func裡面的this是誰
},
render:
function () {
return (
<div
style={{opacity: this.state.opacity}}>
Hello
{this.props.name}
</div>
);
}
});
ReactDOM.render(
<Hello
name="world"/>,
document.getElementById('example')
);
|
Ajax
react本身是無法做到這件事的,必須透過其他框架,例如jQuery。React還有個很大的特色是,跟各家框架都幾乎完美相容,低耦合,甚至它已可以做到類似lazyLoad的效果
var RepoList = React.createClass({
getInitialState:
function() {
return {
loading: true,
error: null,
data: null
};
},
componentDidMount() {
this.props.promise.then(
=> 等待ajax取資料回來
value
=> this.setState({loading: false, data: value}),
error
=> this.setState({loading: false, error: error}));
},
render: function() {
if (this.state.loading)
{// 開始資料分析
return <span>Loading...</span>;//資料Loading中
}
else if (this.state.error
!== null) {
return <span>Error:
{this.state.error.message}</span>;
}
else {
var
repos = this.state.data.items;
var
repoList = repos.map(function (repo, index) { // map在寫react中也常用到,作用類似forEach把陣列資料處裡回傳(angular 就是 ng-repeat)
return (
<li
key={index}><a href={repo.html_url}>{repo.name}</a>
({repo.stargazers_count} stars) <br/> {repo.description}</li>
);
});
return (
<main>
<h1>Most
Popular JavaScript Projects in Github</h1>
<ol>{repoList}</ol>
</main>
);
}
}
});
ReactDOM.render(
<RepoList
promise={$.getJSON('https://api.github.com/search/repositories?q=javascript&sort=stars')}
/>,//$.getJSON是jQuery的方法
document.getElementById('example')
);
|
所以網路上許多人也會用React+backbone讓它變成一個完整的MVC框架,讓它開發起來更加靈活
甚至,React還可以寫在server端,當然前提是你要用同樣是JS開發的NodeJS伺服器。這樣可以在server端直接render出畫面,並且在前端繼續開始react的生命週期。
不過感覺有點像php用echo 輸出html 或 .net用lazor輸出html一樣,前後端就又絞在一起了,成為所謂的全端程式,小編是不太喜歡這樣啦
恩.....下面就nodejs跟react混用,沒啥好介紹的。
React in server
var http = require('http'),
browserify =
require('browserify'),
literalify =
require('literalify'),
React =
require('react'),
ReactDOMServer
= require('react-dom/server');
var App = require('./app');
http.createServer(function(req, res) {
if (req.url
== '/') {
res.setHeader('Content-Type', 'text/html');
var props = {
items:
[
'Item
0',
'Item
1'
]
};
var html = ReactDOMServer.renderToStaticMarkup(
<body>
<div
id="content" dangerouslySetInnerHTML={{__html:
ReactDOMServer.renderToString(<App
items={props.items}/>)
}}
/>
<script
dangerouslySetInnerHTML={{__html:
'var
APP_PROPS = ' + JSON.stringify(props) + ';'
}}/>
<script
src="//fb.me/react-0.14.0.min.js"/>
<script
src="//fb.me/react-dom-0.14.0.min.js"/>
<script
src="/bundle.js"/>
</body>
);
res.end(html);
} else if (req.url
== '/bundle.js') {
res.setHeader('Content-Type', 'text/javascript');
browserify()
.add('./browser.js')
.transform(literalify.configure({
'react': 'window.React',
'react-dom': 'window.ReactDOM',
}))
.bundle()
.pipe(res);
} else {
res.statusCode
= 404;
res.end();
}
}).listen(3000, function(err) {
if (err) throw err;
console.log('Listening
on 3000...');
})
|
學到這裡已經可以開始開發小型的React專案了,還可以有簡單的資料流。
=================================================
我是分隔線,休息一下,喝口水 =========================================================
WTF,簡單資料流??
你應該有發現他的資料流似乎都是父傳子,我想要兄弟相傳,親戚相傳,薪火相傳可以嗎?原則上是可以的,可以透過共同的祖先來資料源與資料處裡。
那問題來了,如果沒有共同的祖先呢?記得React的特性就是東一塊西一塊嗎?而且React當初設計本來就不是為了傳遞資料而設計,所以在資料傳遞上的寫法都會很複雜,所以如果有頻繁的資料傳遞,開發簡單的小程式你就頭大了(說好的React學習曲線平緩呢?),所以這時候官方就提出了一個設計模式Flux,看清楚我講的不是框架,不是語言,是設計模式!!
那這個Flux又是何方神聖呢?這個.......我們就留到後話再說吧!
訂閱:
文章 (Atom)