2013年7月25日 星期四

ng-options的一點小注意事項!

前天我寫了一個 Angularjs 的 select 連動功能,發現一些使用上會忽略的事情特在此紀錄一下!

有寫過 Angularjs 的人就會知道 select 跟 ng-options是多麼的好用!

其中只要 ng-model榜定一下,我們選了什麼立刻就反應回去我們的model!

也因此我們可以透過 $watch() 監看我們綁定的值或是用ng-change這兩種方式來觸發選取後的動作!

這兩種方是我都試過但我個人偏好使用 ng-change ( 主觀的只是一種 fu.....XD

但我遇到的一個問題是用 ng-options 的時候 select 會有空白選項.....

難道我遇到了傳說中的「留白」.....

在藝術或設計手法中適當的留白可以營造一種氣氛! 襯托出一種心境上的氛圍!

但在程式上這就叫做「BUG」...... ( 怎差這麼的多.....

後來我發現會有這問題其實是因為我們 ng-model 一開始的初始值是空的啦!

只要給一下初始值就不會「留白」囉!

例如:
<select ng-model="township.ZipCode" ng-options="township.ZipCode as township.Name for township in areas" ng-change="townshipChange()"></select> 

如果一開始我們的 scope.areas 是[],就會有這問題!

解決方是就是不要讓它是空的就行囉!

2013年7月22日 星期一

Angularjs 搭配 SVG!

上個禮拜我在關心一個問題! 那就是用 Angularjs 怎樣畫圖比較方便!



現在再web上畫圖不外乎幾種常用方法:

1.用SVG (向量繪圖)
2.用CSS (就像我上一篇那樣畫法)
3.用Canvas (html5的新標籤)

有些人可能會覺得為什麼要在web上畫圖而不直接用圖片就好呢?

我自己是覺得啦! 因為用圖片做一些動畫沒有上面方法方便,如果有很多變化就要很多圖片一直切換很麻煩....又很占空間效能!

另外如果想要圖片上某些位置觸發某些事件這樣的功能!

我就還要切圖片切出一個個的範圍然後針對圖片的某個範圍寫事件...這也很麻煩!

像我之前寫過一個計算機!

用一個計算機的圖片在 photoshop 中切出一堆範圍,然後在這些範圍寫 javascript 事件!

比如要算 10+25 

1是一個範圍
0是一個範圍
+是一個範圍
2是一個範圍
5是一個範圍

雖然功能也是能完成啦! 但這樣多累阿!  寫起來程式碼又很亂!

所以某些時候真的還是要用上述那三種方式畫圖會比用圖片還方便!!

也因為這原因,我就在思考這三種方式怎樣跟 Angularjs 最好搭配!!

Canvas方法因為是直接在 Canvas 標籤裡面呼叫繪圖API來畫圖,所以我感覺跟 Angularjs 搭配怪怪的! 因為沒地方可以用那些 預設的 directive 啊!  

CSS方法則是畫圖的數據資料都放在 <style></style> 裡面,但 Angularjs 又不能控制外部樣式的內容! 行內樣式硬要控制好像可以控制啦! 但應該沒人用CSS行內樣式畫圖的吧!  (那會瘋掉...

而SVG這東西其實我完全沒碰過,所以我去找了一下資料,學了一下要怎用! 後來我找到一篇文章還不錯! 

如何在 SVG 與 Canvas 之間選擇

雖然現在用Canvas來畫圖是個顯學! 

但文中也比較了一些優缺點! 用Canvas來畫圖還是有缺點的唷!

好! 回到重點!

在我研究完SVG如何使用之後!

我自己覺得 SVG 跟 Angularjs 應該可以搭配得很好!

因為SVG是用很像標籤的東西在畫圖,格式就像下面所示:

<div>
    <svg>
        <polygon></polygon>
        <polygon></polygon>
        <polygon></polygon>
    </svg>
</div>

座標、顏色等的屬性我都省略了! 但看整個結構可以發現! 它就跟我們一般的網頁標籤一樣! 所以比如我們要在某個多邊形加一個按下事件就可以這樣寫:

<div ng-controller="myController">
    <svg>
        <polygon ng-click="select()"></polygon>
        <polygon></polygon>
        <polygon></polygon>
    </svg>
</div>

所以我個人覺得啦! Angularjs 跟 SVG 搭配還挺不錯的! ( XD....

剛好今天LION大大交代我改CMS這案子的一個東西!

就是要加色碼選擇器!

我後來用SVG做了一個127色的色碼選擇器如下所示:


使用者只要 mousemove 進一個多邊形就會回傳一組16進位的色碼進去程式中!

我本來想要寫成 directive 但後來太客戶在催太趕了!

我來不及寫成 directive 所以就先寫成一般的方式!

等我有空的時候再來把它改寫成 directive! 這樣就可以多個地方重複使用囉!! ^ . ^

2013年7月19日 星期五

練習用css畫圖

CSS這東西看似簡單! 但其實富有很多變化!!

所以今天我就自己給自己出了個題目來練習一下!!

成品連結如下:
http://plnkr.co/edit/S5fL0JTeJE8eiLOEJBXc?p=preview

其實做這東西是要想要練習一些我以前沒用過的CSS功能!

1.:after 和 :before 擬元素!
2.畫三角形
3.畫橢圓形
4.畫梯形
5.還有position的使用( 雖然我知道 absolute 和 relative 作用但有時很複雜會分不太出來

我的做法是先在illustrator中畫好設計圖! 然後再去寫CSS!

先在illustrator中畫好的話,我覺得我在改寫成CSS的時候對於空間位置、物件大小和色彩比較好掌握!

不然直接憑空寫成CSS對我來說還有點難度! ( 可能再多練個幾次應該可以吧...

實做過後我覺得 :after和:before還不錯用!

好用在於可以省下一些標籤語法! 而且如果原本的Dom物件移動的話跟著 :after(或:befort)的Dom物件也會跟著移動! 這樣感覺可以省一些做動畫的程式碼!

然後畫圖的部分其實基本上都是靠改 div 的 border去做!

其實我本來不會畫橢圓!

因為雖然圓角指令很簡單! 比如就一個 border-radius:10px 就好!

但是如果你只是一個長方形下圓角命令!

畫出來的形狀是「膠囊型」不是「橢圓型」! ( 這差很多......

後來我發現若寫成 border-radius:10px / 5px 這樣就會變成橢圓形!  (5px 只是舉例!

針對不同的長方形要用不同的數值!

後來我自己試過一些數據後發現一個簡單的比例原則!

如果說你的方形長100px寬50px!

那圓角的比例只要這樣寫 border-radius:30px / (30/100/50) px!

這樣就會變成一個正常的橢圓形了!

而至於三角型和梯型呢! 其實都是用 div 的 border 來畫的!

兩個的概念其實一樣!

因為 div 的邊框會以 對角相接的方式接起來!

所以只要充分利用這點就可以把三角型畫出來!

舉例來說

border-top: 25px #fff solid;
border-right: 20px red solid;
border-bottom: 2px greed solid;
border-left: 20px blue solid;

這會畫出4個三角形! 第一個屬性值是三角形的高! 第二個屬性質是顏色! 第三個是框線樣式!

最重要的是第一個屬性值! 靠這個屬性值我們就可以畫出各式各樣的三角形!

而梯形和這同樣道理! 只是梯形多了一個上底! 而上底就是以 div 的盒內距離來做!

比如說設定 width:50px; height:50px;  那上底就是50px!

有個心得!

因為要計算一堆長寬高和比例數值的東西! 計算機超常用到的....

以後畫這個一定要準備一台電子計算機在身邊! (附屬應用程式的小算盤不好用....


其實畫完之後我有試著寫一個directive的行為來做無限loop的動畫!

var setClass=function(){
       element.removeClass("effect").addClass("effect");
       $timeout(function(){
           setClass();
       },3000);
}
setClass();

我讓它不斷呼叫自己,雖然它也真的有不斷在loop了!

但動畫效果只跑一次! 因為 removeClass 沒有作用! 但 addClass 有作用!

以致於 effect這個 class 就一直存在標籤裡不會被 remove 掉所以無法達到不斷動畫的效果! > <

為什麼 removeClass沒有效果呢? 這我可能要找時間再測試看看!.....

http://plnkr.co/edit/M25mQzUzi5YEx2qdTYvA?p=preview

2013年7月18日 星期四

修改後端model初體驗!

今天我深深體會到技術真的是日新月異! 從事資訊工作真的是處處充滿驚奇!

photo credit: babasteve via photopin cc

今天 LION 大大教我如何在後端修改 Model 然後自動更新資料庫欄位!  ( 他稱這叫作 Migration

他教我這種先寫程式然後去修改資料庫的方式叫作  Code first !

反之,先改資料庫然後再動程式的方式就叫做  DB first !

雖然我之前也寫過C#,但我從來不知道有 Code first 這種東西!

這真是太有趣了!  今天真的是長知識了啊! XD

感覺上 Code first 真的是很方便!  Model 改完下個指令 DB 便隨即更新!

不像我以前還要先開資料庫起來,然後自己打欄位名稱! 

然後再回到程式裡面再寫程式! ( .net 跟資料庫溝通我只會用很古老的 ado方式.... 嗚!

後端果然也是變化萬千深奧地很呀!!...

其實不只 Code first 讓我覺得驚奇!

之前剛進入CMS專案的時候我也被 Breezejs 驚奇到!

我之前從來不知道 Breezejs 這東西!  

雖然現在對它的詳細細節也不是說很清楚!

但我在改過幾個系統問題之後! 大概知道它是怎樣操作!

感覺上它是用控制物件方法的方式在做資料庫操作! 

單純跟後端要資料來,送資料到後端去!

我覺得  Breezejs 的操作方式有一個很大的特點是我要學習的觀念!

之前還為此問了 LION大大兩次.....

就是 Breezejs 是針對某些 record 改動它的 flag 然後再透過 saveEntity 去更新資料庫! (此段引用自LION語錄

我把它理解為這就很像我們去大賣場買東西!

在賣場裡面我們一定不會拿一個東西就去結帳一次! ( 除非你要蒐集發票啦.....

大多數情況一定是把要買的東西都一次拿齊! 然後到櫃台一口氣結帳!

結帳就是 saveEntity! 結帳後資料庫才真正改變!



photo credit: Walmart Corporate via photopin cc

所以啦!

做批次功能的時候! 就是把批次選取起來的東西都先標記起來! (我想成把東西放到購物車  XD

然後按下一個按鈕後,這按鈕的動作就很像結帳的過程,更新了資料庫!

其實程式操作的邏輯跟我們現實生活中的規則還挺像的啊! 你說是不是!   XD

2013年7月17日 星期三

神奇的directive!

今天我的工作心得有點像大雜燴XD

因為有參雜一些之前犯的錯誤以及今天的新發現,所以跟前兩天的文章不一樣,比較不是聚焦某一點的內容,但我會盡量整合的好像是在講同一件事啦.....


photo credit: markchadwickart via photopin cc

在Angularjs的世界裡面,有一個東西叫「directive」!

這東西我第一次看到的時候是被它那自訂標籤的功能所深深吸引! (真是太神奇了...

能夠自訂標籤就代表我能當神耶!....

雖然它不只可以當標籤,也可以當屬性、類別或comment(這個我不知道中文叫什麼...)

所以我之前就習慣把所有的東西全部打成一包,然後就當成標籤了! 比如下面這例子:

.directive('back',function(){
        return{
            restrict:'E',
            template:'<a class="btn btn-primary btn-small">按鈕</a>',
            link:function(scope,element){
                element.bind('click',function(){
            alert("test"); 
                })
            }
        }
    })

html 如下:

<back></back>

這乍看之下好像很乾淨是吧!

但保哥針對這作法提出了幾點隱憂,我覺得滿有道理的,整理如下:

1.外觀寫在template裡面,要動任何外觀都要再改template,並不彈性
2.外觀和行為全部混為一談,並不好維護
3.在一個標籤上雖然可以自訂一堆directives但根本沒意義,還不如用簡單的attribute來做

第三點白話意思就是「搞那麼複雜幹嘛啦! 有更簡單的做法幹嘛不用! 」

那更簡單的方法是什麼呢?

我從保哥給我的了一個jquery的例子中找到靈感:

$('.btnBack').on('click', function(e){
        e.preventDefault();
        var uri = $(this).data('url');
        if(url)
        {
              alert('This url is ' + url);
        }  
});

html如下:
 <a href="#" class="btnBack" data-url="#/Account">回上頁 (代入 data-url 屬性)</a>

有看到一個陌生的東西嗎? data-url ?

後來我才知道,原來html5可以自訂屬性耶! 用法格式就是 data-*

如此看來,用directive寫一堆自訂的directive 屬性好像真的有點多此一舉耶!

只要我能夠抓到我所自訂的 data-* 屬性值,我又何必用一堆directive attribute,然後又在directive的scope中寫一堆"@","=","$"呢?

是不是!  是不是!

這真的有如醍醐灌頂耶!

但問題是 jquery 可以用 data() 或 attr() 來抓屬性值! 但 Angularjs 呢?

哈哈! 這東西今天被我找到了!

救世主降臨!


photo credit: Waiting For The Word via photopin cc

 $observe 就是救世主!

舉個例子,有個html 長的如下:

<a class="btn btn-primary btn-small back " href="a.htm">回上一頁</a>

那我要怎樣直接抓href這屬性的值呢? 做法如下:

app.directive('back',function(){
        return{
            restrict:'C',
            link:function(scope,element,attr){
                attr.$observe('href', function(actual_value) {
                    alert(actual_value);
                });
           }
        };
    });

看到那段紅色的程式碼了嗎?

那就是答案!

所以囉! 如果我們有其他額外的參數要作為行為的判斷依據,就自己加 data-* 然後再來抓這值就好囉!

這樣是不是比寫一堆directive attribute清楚多了呢!   ( 好像是....XD

另外提醒一點啦! 如果自訂屬性是 data-count

那麼要抓它的值的語法是 attr.$observe('count', function(actual_value) 這樣唷!!

不要打成 'data-count' 囉!!

說個補充,有一次我在寫 directive 的時候發生了很奇怪的事情!

好恐怖! 超級恐怖!


photo credit: Bob Jagendorf via photopin cc


那就是兩個一模一樣內容但名稱不一樣的directive,一個總是好的但另一個總是沒效果!

這兩個directive的名稱分別是 myPicture 和 pic

叫myPicture這個directive就是沒有反應! 怪事勒!

後來我請教了我們的LION大大,試了一會兒!

後來我們得到一個結論!

結論就是「名稱只能小寫」.....

只要有大寫或符號(包括底線)那麼這個directive就會沒有作用....

原來可以大寫! 我一直搞錯「-」這符號原來是要寫在標籤裡不是寫在名稱.....( 我是阿呆

但directive的名稱有任何符號還是會失效唷!! 

切!.....  害我改了好久想說是哪裡中猴了哩.....Orz


2013年7月16日 星期二

打造網站步驟讀後心得

今天晚上保哥跟我們上了一門angularjs架構的課程!

講解了一些常用功能的「廬山真面目」

比如: module怎用、比較正確的controller寫法、model怎麼用、facades是什麼...

聽完之後躍躍欲試!  ( 雖然感覺不是很容易...XD

photo credit: Jiuck via photopin cc


課程結束之際保哥特別囑咐要看一篇文章

網站建置不是件簡單的事 @ 打造網站的步驟

看完之後真的是感觸很多,尤其是視覺設計那一個部份真的是說的太...貼...切....了啦!

文章中的那部影片我記得我之前也看過...

而且我還記得那時許多對台灣設計心灰意冷的朋友們看完之後又重新認命的工作去...

原因是「原來日本也是這樣啊」 ( 看來全世界都一樣啦.....

說真的設計真的是一個很矛盾的領域!

另外,文章中有提到一點我也真的是心有戚戚焉...

後期工程師調整網頁常常成為冤大頭...

被PM和Designer雙重夾攻之下,真的是很慘耶! (我是還沒被夾攻過啦! 但文章的情境有描寫出來....

但我有在思考一個問題,文中提到的「網頁版型 (HTML, CSS) 在套上程式之後,網頁就大亂了」問題!

這可能就是保哥常說的彈性吧! 彈性不好一套就掛了.... 悲劇....

但要怎樣寫得很有彈性還真的是一門學問呢!!





javascript之多重影分身之術!

聽說「人呆看臉就栽」,今天我的臉看起來一定是特別地呆><

photo credit: Xosé Castro via photopin cc

我陷在一團泥沼中許久不能動彈,只能稍微動動手,動動腳....

靠著我最常用的console.log不斷找尋蛛絲馬跡,最後答案揭曉....

不要罵我幹嘛不開門見山,讓我鋪陳一下咩~ 氣氛氣氛...

開始進入主題吧! 其實故事是這樣的.....

今天我寫了一個批次刪除資料的功能!

相當然爾,批次大概就是用迴圈來作囉!

在jquery裡面就是$.each() ; 在Angularjs 裡就是 angular.each(),反正用法都大同小異啦!

然而恐怖唷! 恐佈到了極點的事情是...如果要loop的資料在loop裡面變更了那可怎麼辦?

比如說我有一段程式如下:

$.each($scope.data, function (key, value) {
    if (value.selected == true) {
        removeList($scope.data, value);    //在$scope.data中刪除value這資料($scope.data是array)
    }
})

就字面上解釋就是看陣列有多少資料一五一十的跑一遍,如果資料被選取就把他刪除掉!

see...簡單易懂!

但我後來發現這樣作法,我array明明就有兩筆資料,但老是都只跑一回....

後來我想到了,阿我是在搞笑喔!removeList把資料刪掉了當然會少一筆...

好吧! 其實我怎會不知道呢?  我忽略的是它會反映回去each裡面....

我不知哪來的想法,一直都覺得在開始跑each的時候array裡的資料就是原本的那些...

這是for迴圈語法的餘毒未清嗎? (因為通常會先去知道length....

不管如何,知道問題所在當然就要解決它囉啊!

第一個想法 

var temp=$scope.data; 
$.each(temp, function (key, value) {
    if (value.selected == true) {
        removeList($scope.data, value);   
    }
})

想法很簡單就用temp當成迴圈的資料,刪$scope.data而不要刪temp這樣總行了吧!!

.....

...

..

結果呢...答案揭曉! 不行........

$scope.data和temp會互相參考,達到一種你儂我儂、生死與共的境界!

所以呢!  var temp=$scope.data;  這動作我就把它當作互相「結拜」的動作!

結拜的基本宣誓詞就是「雖不能同年同月同日生,但願同年同月同日死」...

這兩個拜把兄弟非得要同甘共苦不可了....  (寫程式還能看連續劇真是不錯

話說這保哥之前給我們上js的課的時候好像有稍微講到。

好啦! 好啦! 我回想起來了....同一個記憶體位置啦...XD

所以怎辦呢?

我呢! 就另外宣告一個空白陣列然後再把值填進去囉! 如下:

var temp=[];
$.each($scope.data,function(i,v){
    temp.push(v);
})

這樣一來! 一個嶄新的temp資料就誕生了! (感動....

這過程我把它叫作多重影分身之術!

photo credit: Xosé Castro via photopin cc

沒錯! 這新誕生的資料就如同鳴人的影分身一般,每個都是獨立的! 

就算一個影分身被曉的成員幹掉,也不影響其他的影分身! (侯賽雷阿!~



2013年7月15日 星期一

ng-repeat是多胞胎產生器!

在 Angularjs的世界裡,我覺得ng-repeat這玩意兒應該可以算是前5名常用的功能吧!

 photo credit: Spigoo via photopin cc
沒錯! 就像上圖一樣! 只要有了ng-repeat一次生出多胞胎再也不用大粒汗小粒汗!

所有重複性的table資料、重複性的list資料、重複性的div資料....(我現在不斷重複也是...= =

都可以透過ng-repeat來迅速完成!!

但是, 我們都知道雙胞胎不管長的多像, 還是有些微的不同!

這可能是老天爺為了要給辛苦的媽媽好分辨用吧! 就感心耶!!

所以啦! 當你的孩兒們(model裡的資料)都長的一模一樣的時候,

oh my god~ 神的審判之槌就會降臨,F12按下去,Error之槌就會共尬力咪咪冒冒...$#&$@!

比如說,我的model data 長的如下:

$scope.model.chlidren=["大寶","大寶","大寶","大寶"];

html長的如下:

<ul>
    <li ng-repeat="model.children">
</ul>

這時候F12審判之神會告訴你:

My dear , Duplicates in a repeater are not allowed.
(翻譯: 親帶的,你的多胞胎因長得一模一樣有基因改造之疑慮所以予以駁回!)

蝦密! 我黃豆吃太多了嗎? 政府沒有把關! 現在到底還有什麼可以吃...

沒關係! 在Angularjs 的世界裡,好險我們不用肝臟來代謝毒素,也不用害怕毒素會殘留在體內!

只要把<li ng-repeat="model.children">這句改成,<li ng-repeat="model.children track by $index">即可!

我是這理解的,孩子長得一模一樣沒關係,給他們各自不一樣的「胎記」就好,而這胎記就是$index啦!

神奇唄!

PS: Angularjs世界是可以這樣啦! 但現實世界怎麼辦?  現在還有什麼可以吃的啦 >< 喔我的天..


開張文!!

阿福兔E之家開張囉!

其實這是我第一次寫Blog! 

雖然之前一直都寫的計畫!  ( 計畫總是那麼美好....

但總是沒個目標不知道要寫什麼....暈~

剛好的是! 今年7月我正式成為多奇家族的一員了!!

開始作著我之前就一直十分想做的網頁前端工作 ^.^ YA比!

然後保哥也十分鼓勵我們寫些技術文章!!

一方面是能作為和他人交流的一種方式!!  

另一方面是幫助自己記憶 (唉唷!! 人越大記性越不好咩!~

所以就稱著這次機會終於開始我的部落格生涯囉!!

我會記錄著前端工作的點點滴滴! 

每天記錄一點! 總有一天會變一大點是吧! XD

給自己一個期許! 我要成功! 我要成功! 加油! 加油! 加油!