[GoogleMap]基礎使用記錄

最近要研究google map真的是挫折百般,網上一堆說很簡單操作的可是我用起來就是一直覺得怪怪的XD,也許我沒有寫程式的天賦,但至少要知道怎麼努力。

其實簡單來說Google map就做兩件事情:
你給他地址會得到經緯度並定位,你給他經緯度可以得到地址並定位!

這就是最基本的使用方式,在HTML的程式碼裡面只需要一行:

<div id="map_canvas" style="height: 300px; width: 100%;"></div>

當然大小樣式是可以自己決定的,那就來做使用吧!

給予經緯度定位

如果你真的有經緯度的話是最輕鬆定位的哦!而且只要寫:

var map = new google.maps.Map(document.getElementById('map_canvas'), {
    center: { lat: 25.037522, lng: 121.563501 },
    zoom: 17
});

其實HTML的div tag裡面就會出現最基本的畫面了,這個座標會出現市政府附近的地圖。
center是輸入座標的地方,需要是一個物件。
zoom是地圖的縮放大小數字越小則可以看到的地方更多,17是最基本的。

以使用者角度來看沒有標記點只給我一張地圖感覺很吝嗇糟糕,所以我們在來改變一下:

//這邊我把座標拉出來處理,map 跟 maker是共用的也會更好讀懂

var position = '25.037522,121.563501';
var latlng = {
    lat: parseFloat(position.split(',')[0]),
    lng: parseFloat(position.split(',')[1])
}
var map = new google.maps.Map(document.getElementById('map_canvas'), {
    center: latlng,
    zoom: 17
});
//我們的標記點登場~

var marker = new google.maps.Marker({
    map: map,
    position: latlng,
    icon: 'https://maps.google.com/mapfiles/ms/icons/blue-dot.png'
});

這樣有沒有很像Google map了呢?但對使用者來說我們不可能會知道座標在哪,就像坐計程車的時候我們不會跟司機說『我要去25.037522,121.563501』他應該只會載你去醫院,必須要說我要去臺北市政府,就像我們要輸入到google map收尋一樣!

給予地址定位

所以我們先來做個簡易的收尋欄位吧!

<input class="userinput" type="text">
<div style="width: 60px; height: 20px; border: 1px solid" onclick="search();">Search</div>
<div id="googlemap"></div> 

再來新增一個getLatlngByAddress用中文地址得到座標的函示:

function search () {
  var address = $('.userinput').val();//得到剛剛輸入的地址字串

  var position = "'',''";
  var latlng = {
      lat: parseFloat(position.split(',')[0]),
      lng: parseFloat(position.split(',')[1])
  }
  var map = new google.maps.Map(document.getElementById('googlemap'), {
      center: latlng,
      zoom: 17
  });
  var marker = new google.maps.Marker({
      map: map,
      position: latlng,
      icon: 'https://maps.google.com/mapfiles/ms/icons/blue-dot.png'
  });
  
  getLatlngByAddress(map, marker, address);
  
  function getLatlngByAddress(map, marker, address) {//重新定位地圖位置與標記點位置

    var geocoder = new google.maps.Geocoder();
    geocoder.geocode({
      'address': address
    }, function (results, status) {
      if ( status === google.maps.GeocoderStatus.OK ) {
        var getLatLng = results[0].geometry.location;

        map.setCenter(getLatLng);  //將地圖中心定位到查詢結果

        marker.setPosition(getLatLng); //將標記點定位到查詢結果

        marker.setTitle(address); //重新設定標記點的title

      } else {
        alert('找不到哦!');
        $("#geo-UpdateDemand").text("");
      }
    });
  }
}

Google map的geocoder也可以用經緯度定位取得新地址和地址名稱,這樣可以用來做移動座標的動作,這邊簡單記錄一下基礎的東西,很多資源網路上查也會有,再來Google map存在著一些地雷,像是畫面顯示很容易遇到破圖,這時候可以試著用setTimeout或者Google map不知道哪一版有提供resize的事件去做刷新Google map的div tag,希望下次不要再卡關這麼久囉XD!

[socket.io]初探socket client端使用與設置

工作上要實作一個聊天室,網路上最簡單的套件就是socket了,我是負責客戶端的程式碼,所以伺服器端的我不熟XD,但是socket的文件寫的不是很完整讓我摸了兩天才大概知道怎麼用囧,所以在這邊做一下記錄。

先在這邊放上socket的網站
還有socket的Github

初始連線

我們先假設你的socket已經安裝好,而且親愛的後端已經把伺服器寫好了,這時候我們要先初始化socket的連線:

var socket = new io.connect('伺服器地址和port');

此時我們來看看Github上socket裡doc的Client API文件,裡面是關於客戶端的設定還有操作,可以看到中分類有兩個Class,一個是io.Manager是關於socket初始化的管理還有io.Socket是關於socket的動作,剛剛我們那行程式碼已經是初始化完socket了所以我們看動作的部分有內建的Event

文件裡的Event是內建的,像是Event: 'connect'代表連線後要做的事情,使用方法:

socket.on('connect', function(){
    console.log('Socket connect!);
});

伺服器收接到連線成功之後會自動發射一個connect給客戶端,這樣就完成最簡單的連線囉!當然也可以把錯誤的連線設定好:

socket.on('connect_error', function(){
    console.log('Socket has something wrong!);
});

emit和on的動作

socket伺服器端和客戶端的聯繫全程是使用emit(發射)和on(接收)去溝通的

不論哪一端只要emit(發射)一個命令,另一端就一定要有on(接收)去接收他,除非是內建的Event,就像是剛剛的連線一樣,伺服器就不用特地再寫socket.emit('connect');發射給客戶端說連線成功。

如果連線成功,接下來就可以很自由的玩基本的即時聊天功能囉!例如:
簡單的伺服器端

sever端
socket.on('New chat', function () {
    socket.emit('Reflash');
});

搭配客戶端

client端
function submit () {
    socket.emit('New chat');
}
socket.on('Reflash', function () {
    reflashView();
});

這樣就是一個簡易的聊天互動了!

Manager(初始化管理)

這邊真的是研究了一段時間才知道怎麼用,可以先看網頁版的socket,他的敘述大概是一個新的Manager可以重複給sockit使用,其實我不太懂意思,但是如果你一個頁面只需要一個sockit的話應該是不用理這個,不過重要的是如果你的聊天頁面網址是http://localhost:3000/users,在連線指令只要下:

new io.connect('http://localhost:3000');

就可以了!

此時再來看看Github上socket裡doc的Client API文件Class: io.Manager有很多manager.something的東西,譬如說設定最多連線次數的東西manager.reconnectionAttempts([value]),使用方法如下:

var socket = new io.connect('伺服器地址和port',{
    'reconnectionAttempts': 5
});

這樣就行了!

經驗談

接下來稍微講一下socket特性的地雷,所以我才會覺得他的文件不是寫得很完整XD。

剛剛manager的範例是設定最大連線次數5次,但是如果沒有設定'autoConnect': false的話他還是會繼續嘗試連線然後不斷報錯喔囧,但要記得!!如果設定了false要主動使用socket.open();去打開連線。

再來'reconnection': true是代表連線中如果斷線了要不要自動重新連線

'reconnectionDelay': 2000,'reconnectionDelayMax': 5000,'randomizationFactor': 0.8似乎是一國的,是調整每次重新連線的時間,但是要怎麼切確調整我不太熟悉,不過以上是我的設定。

'timeout': 5000是連線五秒還沒有成功的話就跳connect_error,預設似乎是20秒。

我會更希望不斷提醒使用者scoket在做什麼,譬如說每次重新連線我都顯示一個提示,使用它內建的Event:

var connectTime = 0;
socket.on('connect_error', function () {
    console.log('connect_error');
    if ( connectTime < 5) {
        connectTime ++;
    } else {
        socket.close();
        console.log('Failed too many times, please check internet!');
    }
});

為什麼要再下socket.close();呢?我們不是設定reconnectionAttempts: 5了嗎

這是真的把socket的連線全部斷開,一定要再使用socket.open();才能重新開啟連線,這是比較保險的做法,因為不知道為什麼有時候他會不理我的reconnectionAttempts限定次數繼續爆衝連線啊囧。

以上是小弟跌跌撞撞使用socket的經驗XD,希望能幫助大家也更希望有高手指點迷津。

[讀書心得]重新定義工作

這本書本來是以為會講偏向工作意義的東西,但他大多是給一些未來工作型態的觀念和想法。

未來工作五大趨勢

  • 新行為
  • 技術
  • 千禧年員工
  • 機動性
  • 全球化

新行為

現在的工作因為有了新科技使得許多問題有了新的解決方法,例如以前的電腦問題都要請IT部門來解決,要拖非常久的時間,現在自己上網GOOGLE或許就有解了。

千禧年員工

未來千禧年時代將會佔勞工人口約七成以上,這代表新的想法和觀念都會衝擊現在的公司和產業。

機動性和全球化

現在網路的方便可以讓員工隨時隨地的關注項目的發展甚至突發狀況,而現在的企業也不能止在一個地區發展,要到別的地方也能發展,甚至全球。

員工敬業度很重要

首先什麼是敬業度?每個人和每間公司定義一定不一樣,但敬業度可以說是一個員工願不願意全心全意且負責的做好工作。

現在金錢已經不能完全的提升敬業度,除了重複性很高的機械性工作,但這種工作取代性也很高,也即將越來越少,如何有效提升員工已經是變成一個企業課題。

未來工作七大原則

  • 靈活的環境
  • 自己定義工作
  • 共享信息
  • 新的協作
  • 誰都可以當領導人
  • 知識型員工轉變為學習型員工
  • 自由的學習並且自由的教導別人

什麼是自己定義工作

讓員工挑選自己有興趣的工作項目,員工會自然做出最好的效果甚至突破自己,也會學得許多東西,再來教導別人成為一個循環。

什麼是學習型員工

其實學習型員工最重要的就是學會不斷適應,也就必需不斷學習新的知識和技術。

傳統的管理已經過時且沒效率

傳統的考核以及不斷開會等等其實是很浪費時間的,甚至有統計過一家知名公司他們的員工覺得這種事情沒有意義的人數高達98%。

未來員工需要的重要技能

要有領導能力,而且有專業的技術在身上可以帶領團隊,尤其溝通上也十分重要。

什麼是領導者

領導者需要學會從前方跟隨,意思就是要幫其他跟跟隨者排除他們的困難和障礙,而不是一昧地自己往前衝。

建立弱關係

當項目一變大變複雜就需要各方人士的幫忙與協助,不是說要拉他加入團隊,而是每個人甚至團隊都可以迅速的溝通並互相幫忙解決問題。

如何建立沒有管理階級的制度

現在無管理階級的制度是一種趨勢,代表每個員工都能充分發揮自己的才能和解決項目的問題,但公司必須要充分體現公司的價值觀,並且找到適合的人才才行。

看完之後覺得現在員工的趨勢就是營造自己的品牌,並且有快速適應新事物的能力,企業也不能再過度用傳統過時的管理方式限制人才的發揮,但個人認為在台灣還很難改變這樣的氛圍環境,畢竟這樣有十分把握能讓公司賺錢的策略和產品才能這樣培養。

[Angular-1]$http post formdata基本使用

我的工作開發框架是使用Angular1,在串接API的時候$http讓我們方便許多。

首先原生的Ajax使用可以參考這篇MDN,那這篇紀錄一下怎麼用$http上傳formdata的東西:

var dataObj = someObj;
console.log(dataObj); //要上傳的東西,上傳前看一下是好習慣。

var formdata = new FormData();
angular.forEach(dataObj, function (value, key) {
    formdata.append(key, value);
});

$http({
    method: "POST",
    url: "URL",
    data: formdata,
    headers: { "Content-Type": undefined }
}).then(function (response) {console.log(response)})
  .catch(function (response) {console.log(response)});

其實最需要注意的是headers : { "Content-Type": undefined }這裡的設定,查到很多舊資料是設定false,但問過一些人之後似乎是有一次angular的改版要變設定為undefined。

第二個設定是有人把data: formdata使用一個$parse過濾要上傳的東西,變成data: $parse(formdata),但我沒有成功過,那似乎是翻譯angular的語法,已經有點不相干了。

以正常的物件post基本formdata的時候就使用上面那些設定就好囉!有特殊的使用就要再去了解了headers要如何設定。

[Angular-1]type file 使用原生 onchange 呼叫 angular function

我的工作是以Angular1框架做開發,遇到了需要上傳檔案的問題。

基本的方法查詢後想說以:
<input type="file" ng-change="upload(this)">
這行程式碼做開發,但發現ng-change並不會被觸發,只能用比較特別的方法。

使用原生onchange代替ng-change

那怎麼用原生的onchange呼叫到angular的controller裡的function呢?
直接看範例:

<div ng-controller="uploadController">
    <input type="file" onchange="angular.element(this).scope().upload(this)" >
</div>

這樣就可以觸發囉!
再來怎麼抓上傳檔案的內容呢?在controller裡的function裡下:

function upload (element) {
    console.log(element.files[0]);
}

就可以開始對他進行操作了。

如何呼喚在controller as Ctrl的function?

有參考過John papa的規範一定很熟悉為了程式碼的乾淨會在html下:

<div ng-controller="uploadController as upload">
    <div ng-click="upload.someFn()">click me!</div>
</div>

這樣可以馬上知道someFn()這個function是誰家的controller,那融合剛剛說的用原生的onchange怎麼做到冠上Controller名稱的function呢?
直接看範例:

<div ng-controller="uploadController as uploadCtrl">
    <input type="file" onchange="angular.element(this).scope().uploadCtrl.upload(this)" >
</div>

這樣controller裡的程式碼就能繼續照著規範走保持整潔囉!

底層怎麼走的還不太清楚,小小的工作心得分享!

[Angular-1]controller的父子關係變數溝通(通訊)測試

最近在重整公司專案一個controller一個頁面吃到完的hard code,網路上找了許多規範,大家都很推johnpapa的angular規範,但在父子關係的controller之間的通訊是如何呢

在這邊紀錄一下我直接用實測的方式做出來,還不是很清楚底層發生了什麼事情。

父子都注入$scope的話

在這邊我就不多贅述創造module的部分,只針對controller寫範例:

<div ng-controller="parentCtrl">
    {{ father }}
    <div ng-controller="childCtrl">
        {{ son }}
    </div>
</div>

這是我公司最一開始html的寫法,我想也是大家剛接觸angular的寫法,我來看看JS的部分(參照johnpapa的規範寫兩個JS檔案):

parentCtrl.js
angular
    .module('app')
    .controller('parentCtrl', parentCtrl)

    parentCtrl.$inject = ['$scope'];
        
   function parentCtrl ($scope) {
        $scope.father = "hasFather";
        $scope.son = "hasSon";
   }

接下來創造childCtrl,裡面沒有任何的程式碼,純粹console.log變數出來看:

childCtrl.js
angular
    .module('app')
    .controller('childCtrl', childCtrl)

    childCtrl.$inject = ['$scope'];
        
   function childCtrl ($scope) {
        console.log($scope.father);//hasFather

        console.log($scope.son);//hasSon

   }

發現在childCtrl其實就跟parentCtrl共用$scope了!
更明顯的是可以直接在html裡面看到結果,這讓我迷思的一點是大家都說每一個controller都有屬於自己的$scope,但在父子關係的controller似乎不是這樣子

父子使用this去注入$scope的話

在剛剛的例子之後,接下來我們親愛的johnpapa說不要這樣寫,因為html和變數一多會很難以維護,意思就是不要一直用$scope宣告變數,那該怎麼讓變數跟自己的controller綁定?

有一版的angular新增了controller as ctrl的這個功能,現在我們可以很直覺的直接在html裡面看得出這個變數是屬於哪個controller的。

來看看html做了哪些更新:

<div ng-controller="parentCtrl as parent">
    {{ parent.father }}
    <div ng-controller="childCtrl as child">
        {{ child.son }}
    </div>
</div>

使用controller as之後表達式一定要這樣寫才行喔!!
這樣就很清楚知道這個表達式的變數是哪個controller裡面的。

那麼controller怎麼使用johnpapa所說的this呢?

parentCtrl.js
angular
    .module('app')
    .controller('parentCtrl', parentCtrl)

    parentCtrl.$inject = ['$scope'];
        
   function parentCtrl ($scope) {
        var self = this;
        this.father = "hasFather";
   }

childCtrl也要有自己的變數囉!但是我們依然可以測試一下childCtrl到底吃不吃得到parentCtrl的變數,我們用console.log來查查:

childCtrl.js
angular
    .module('app')
    .controller('childCtrl', childCtrl)

    childCtrl.$inject = ['$scope'];
        
   function childCtrl ($scope) {
        var self = this;
        this.son = "hasSon";
        console.log(self.father);//undefiend

   }

此時html都可以正常顯示的,因為parent.father有正確的在parentCtrl裡宣告,而child.son有正確的在childCtrl裡宣告,但是在childCtrl裡已經找不到self.father的變數囉!

這邊還蠻直覺的,因為畢竟在兩個controller裡面都宣告自己的this,我們也可以在兩個環境都下console.log(this);就會看出他們確實指向不同的物件(有不同的變數環境)

接下來最有趣的東西來了

如果我們在childCtrl把var self = this;拿走呢?猜猜看會發生什麼事?

childCtrl.js
angular
    .module('app')
    .controller('childCtrl', childCtrl)

    childCtrl.$inject = ['$scope'];
        
   function childCtrl ($scope) {
        this.son = "hasSon";
        console.log(self);//會發生什麼事情!?

   }

我在下console.log(self);以前會認為因為在childCtrl找不到self所以向外看到了parentCtrl有self,所以應該會指向他,但是.....BAAAANG!!!

如果沒有宣告self的話他竟然指向了window!!!
WTF??
self不是被我宣告是指向parentCtrl這個物件裡嗎XD?

總之測試告一段落,因為我本來一直苦惱著要怎麼讓兩個controller溝通,網路上查就有三大種方法,第一個自己創service,第二個是使用$broadcast的事件,再來第三個是直接使用$rootScope,在這裡就不在贅述囉!

這是我自己測試出來的,如果大家有什麼好心得可以交流一下囉!

「直播」Nic拉你出坑,HTTP協定,CRUD與RESTful和MVC架構

HTTP協定到底是什麼?

在網路的世界我們看到的網頁進行的任何操作到底發生了什麼事情呢?我們先簡單的介紹兩個動作和三個端點。

三個端點分別為客戶端(Client)服務端(Server,也可以說是伺服器)資料庫(DB),而兩個動作分別為請求(Request)回應(Response)

再來客戶端所有的操作都會發出請求給服務端,而服務端向資料庫拿取剛剛客戶端想請求的東西後在回應給客戶端

其實講白一點就很像我們在電購東西,今天客人(客戶端)想買一台電視,所以他拿起電話打給店家(服務端)說要下訂一台液晶螢幕,這個動作就叫做請求。

再來店家(服務端)收到訂單之後會去倉庫(資料庫)看看剛剛接到的訂單(請求)還有沒有庫存,有的話就會回電話(成功的回應)給客人說下訂成功,即使沒有庫存的還是會回電話給客人說因為沒有庫存的所以沒有下訂成功(失敗的回應)。

而這種互動方式在網路上面就稱為HTTP協定,那我們什麼時候會發送請求這個動作呢?

一般最簡單的就是註冊會員送出的表單就是了,但其實我們打開瀏覽器後輸入的每個網址都是一個請求喔!接下來順勢看看什麼是CRUD與RESTful吧!

CRUD與RESTful

剛剛說的HTTP協定他其實有很多種請求的動作,例如HEAD、GET、
POST、PUT等等還有很多,這些網路上就找得到不用特地背起來,而最常用的動作分別是GETPOSTPUTPATCHDELETE,這些也不用背,因為會常用到然而然背起來。

在以前我們如何對服務端(server)敘述請求的動作?最原始的方法就是直接在網址裡面敘述:

獲取所有使用者資料/getAllUsers
獲取使用者資料/getUser/1
更新使用者資料/update/user/1
刪除使用者資料/delete/user/1

但在Ruby on Rails他發明了更直覺的敘述方法,這種敘述方法就稱為RESTful API

獲取所有使用者資料/GET/users
獲取使用者資料/GET/user/1
新增使用者資料/POST/user
刪除使用者資料/DELETE/user/1

RESTful API最主要的是我們可以直接看到什麼樣的請求動作已經在大寫清楚地述敘在上面

這樣的規範我們得到了兩個最棒的優點:
1.直觀簡潔的resource URI
2.善用HTTP的動詞

老師在這邊有提到一個很特別的事情,就是HTML5只能用GET和POST!!
這樣講起來好像又很弔詭,那到底能不能用呢?

如果是用Rails當服務端是完全沒有問題的!ROR服務端是可以了解這種敘述方法的,事實上RESTful API就是ROR發明出來的!

什麼是MVC架構?

ROR天生就是照著MVC的架構做出專案

先敘述一下在rails的世界裡Router像是總機小姐,可以決定什麼樣的請求會導向哪裡,或者呼叫什麼資源過來。

接下來老師直接用一個例子示範Live show。
例子:使用者新增一篇Orid文章就給他50點經驗值

首先我們先建立Model,先去Routers定義resource,再到終端間下指令新增:
rails g model experience user_id:intege orid_id:integer point:integer

別忘了繼續下rake db:migrate更新資料庫。

之後我們在主要的controller檔案裡面做一個controller:
if @orid.save
do something
end

現在如果新增一篇文章的話,其實資料庫裡已經有點數了,只是我們沒有把View更新出來所以看不到。
測試資料庫有沒有更新成功的方法可以在終端機下rails c,在這個環境把最後一筆資料叫出來看看。

剛剛發生的事情是我們新增文章後呼叫了Router(總機小姐),他了對應的controller(資源)過來幫忙做事情,然後這件事情有更新了倉庫(資料庫)。

剛剛因為在主要controller直接寫邏輯大家會看不懂,所以我們通常會把剛剛做的controller放入另一隻檔案,然後再善用變數命名去讓主要controller更為清楚精簡語意化,像剛剛的controller命名就是可以是@orid.generate_point。

小補充:如果把@(at)拿掉的話只有在此定義的方法裡面使用。

最後要顯示點數給客戶端,所以要在網頁(view)上面開始新增點數的HTML程式碼。

首先可以在最下面可以先拿出資料:
def total_point
experiences.sum(:point)
end

然後在最上面開始寫下這些東西的關聯:
has_many....

最後在畫面上要呈現的地方寫上程式碼 <p> <%= current_user.total_point %> </p>,這個就完全是View的事情了!

小補充:可以在controller寫下程式碼byebug去找出bug,此時網頁的任何操作不會有反應,因為操作的過程和結果都會顯示在終端機開著rails的server的地方。

回顧流程:
Model:資料庫管理人
Controller:機械手臂
View:根據機械手臂顯現出畫面

Q&A
1.現在市場上以手機市場為主,之後會有APP課程嗎?
其實MVC架構是一樣的,所以rails學好觀念再去學APP是很有幫助的,領域完全不同所以比較有可能開相關課程而已。

2.Model有問題就執行刪除數據嗎?
先找出問題再去新增新的再刪除破損的比較乾淨。

3.ROR可以開發遊戲嗎?
效能不會這麼好,也不是這麼齊全。

4.byebug需要安裝嗎?
可以在gemfile安裝。

今天真的是太濃縮了XD,跟本來不及做筆記,大多事情是我自己敘述的,有錯誤再麻煩指點囉!

「直播」Git 入門篇 - Nic

Git是什麼?

Git是一種工具(可以譬喻為時光機)。

以履歷為例子,如果我們每次更新履歷,但是又要把每次的版本留下來,我們的作法就是複製一份履歷當作備份,再對新的履歷進行修改,這樣兩個版本的履歷就要有兩個檔案。

但我們的專案檔案大小很大,也非常快的一直在更新,我們不可能一直不斷的複製備份我們的專案,所以Git這個工具可以把專案維持在一份就好,因為要做新的變動可以一直切分支出去,做好再合併回來,不斷創造節點(就像遊戲的記錄點),想要看哪個節點可以隨時跳回去看。

Github又是什麼?

Github是代碼托管的倉庫

現在其實有很多種的倉庫,但github是目前最熱門的,在這邊先簡單介紹Github最重要的ForkClonePullRequest是什麼東西。

Fork和Clone的迷思

Fork(叉子),就像是把東西(專案)叉進(複製)到自己的盤子(自己的Github)裡處理。
Clone是把Github上的專案複製下載到本地端,所有的更新紀錄也都會一並下載。

Github是一個可以開放code讓世界各地的人協作的地方,我們希望可以讓每個人不斷的把專案更新得更完整,畢竟每個人也許會有每個人的盲點或想不到的功能甚至Bug,所以Github是一個很強大的協作開發工具。

玩過Github的人都知道,其實別人的專案就算沒有Fork到自己的Giuhub裡也是可以Clone下來的,為什麼要多此一舉呢?

在哪裡Clone下來的專案,專案的地址就會指向那個專案位置,也就是說今天沒有先Fork到自己的倉庫(Github)就Clone,在我們push的時候會遵照著地址push到別人的倉庫,但是你沒有別人倉庫的鑰匙是不能push上去的!

如何查看自己地址?git remote -v

當然我們也可以再下指令去更改地址到我們自己的倉庫,但是直接按一下Fork再Clone下來就好何必要這麼麻煩多此一舉呢?

Pull Request請求

Pull Request是發送請求給原作者說可不可以合併我新增的東西。

剛剛說Github是很強的協作工具,那你Fork加Clone專案下來並且更新好之後想要原作者合併(merge)上你的更新就必須發Pull Request請求給原作者,原作者自己按接受後才算是完整的完成這次的合併(merge)囉!

Git flow(工作流程)

外面最正常的團隊開發流程:
1.master是穩定的prodution
2.develop是用來當作開發的分支
3.其他開發都是從develop切出去,最後再合併回來

單人的話:
1.master是穩定的prodution也可以用來當作開發的主要分支
2.其他開發都是從develop切出去,最後再合併回來

合併回master的隱藏好處是會不斷增加自己Github上的Commit數(小綠格),那它代表著下面幾個重點:
1.Github是實力展現的地方
2.預設的branch(master)才會被計算
3.繽紛的色彩看起來很厲害

後面老師有介紹小工具source tree (圖形化的Git工具),在網路上即可免費下載。

安裝後打開新增一個倉庫,把專案加進去,圖形化的介面可以把專案的更新紀錄和流程看得更清楚,裡面也可以有按鈕直接下一些指令(例如commit, push等等)。

最後Nic老師有示範一下的日常開發流程:

實作功能:Job-listing首頁加入使用者人數計算

先創造這次的分支要做什麼功能(這次功能為顯示使用者人數):
git checkout -b users-count切換到這個分支去,如果沒有的話就開啟新分支。

更新完這次的功能後做最後檢查:
git status看更動了哪些檔案。
git diff看檔案裡實際更動了什麼東西。

檢查完後開始下記錄點並更新專案:
git add .追蹤所有檔案。
git commit -m "Add count"下紀錄點。
git checkout master切回主幹Branch。
git merge user-count合併剛剛的分支。
git push推上去Github更新專案。

這裡有一個主宗是希望主幹永遠保持最乾淨

Q&A:

1.Boostrap的格線問題
不好回答,去看文件就有

2.初期抄別人代碼但不夠理解不能變自己的怎麼辦?
一開始不要理解到底,只要能掌握怎麼使用和效果就夠了。
像走路一樣不可能理解到左腳右腳重心放在哪才肯走路,一定是走路不斷跌倒才會學最快的。

3.Git checkout . 有新增檔案會不會也被回朔?
因為新增檔案沒被追蹤過所以不會被回朔,可以用git stash清掉。

4.我的branch切太多還要全部合併嗎?
主要開發一個就好了,其他砍掉吧!

5.table跟柵格系統不一樣在哪?自適應怎麼做?網上有很多做法但不到哪一個才是正確的?
用%數或Bootstrap上的套件就可以使用,table跟柵格系統其實蠻不一樣的可以多看文件,問題太籠統很難回答。

6.我已經切八個分支了怎麼辦?只要合併最新的嗎?
沒錯,專心開發最新最完整的一個分支就好,其他都刪了吧!

7.index和show有什麼不一樣?
index像是農場內的一群羊,show是抓一隻羊出來看。

小結論:

這個基本的工作流程和版本控管真的很重要,但是他雖然很簡單,會遇到的狀況卻是非常多,所以真的還是得上了戰場錯了幾次才會真正體會到Git和Github的精髓啊!

[JavaScript] 將換行符號翻譯成分號&忽略空白字元

將換行符號翻譯成分號

養成開頭大括號跟要做的事情擺在同一行的習慣

不管在哪種編譯器或者可以打字的地方,其實當我們換行的時候電腦是會key上一個我們看不見得符號(這邊用↓當代表)。

但要小心有時候JS會把換行符號↓自動轉變成;,所以我們自己先養成一個好習慣避免這種很難debug的錯誤。

直接看例子:

var a = true;
if (a) {
    console.log('Run without ↓');
}

if (a)
{
    console.log('Run with ↓');
}

你能猜到哪個會執行嗎?其實兩個都會XD,那換一個呢?

function noChange () {
    return {
        status: "I don't have ↓"
    }
}

function hasChange () {
    return 
    {
        status: "I have ↓"
    }
}

console.log(noChange());
console.log(hasChange());

我們會發現第一個return正確的物件,第二個卻return undefined,這是因為retrun後面接上換行符號JS的引擎會自動補上;的關係,所以剛剛的hasChange其實會被翻譯成這樣:

function hasChange () {
    return;
    {
        status: "I have ↓"
    }
}

但在大多數的情況下是沒關係的,例如function、迴圈、甚至在物件或陣列裡面等等,但為了避免這種小又難以解決的錯誤,我們就養成開頭大括號跟要做的事情擺在同一行的習慣吧!

忽略空白字元

JS會忽略空白字元,或使用tab產生出來的空白,但全形的空白不會忽略(不過這個只有在中文輸入法才比較會碰到)。

其實下面的程式碼是可以正常執行的:

var a,
    b,
    
    //this is a pen

    
    pen;
    
a = 1;
b = 2;
pen = // I give it a color

    'green';
    
console.log(a);
console.log(b);
console.log(pen);

其實這是會正常執行的哦!!所以看到別人的專案註解或換行一大堆不用慌,也是看準關鍵字然後保持這個原則就ok了!

「直播」xdite教你克服情緒 & Nic 教你克服 DB

今天是一次兩個講師直撥,那背景音樂我聽出來是let it go很好聽。

xdite教你克服情緒

首先老師先介紹了一本書『腦能量整理術』是一位日本的腦神經權威著作,老師的網站上也有自己整理的筆記,這本書主要在講如何用科學方式控制情緒起伏,讓自己保持正面樂觀提高記憶力。

首先我們最常遇到『學習上』最崩潰的問題就是為什麼學習時間差不多的人做出來的東西會比我牛逼這麼多?

先來想想有沒有辦法讓自己沒有情緒,答案是不可能的,所以再來探討為什麼我們會有這個崩潰感?

大部分的原因是因為自己的大腦跑太快了開始爆衝了,腦袋想了一堆事情卻沒有辦法去實現,這時候焦慮感會直線的上升。

那以科學的角度來看是因為血液裡的血清素降低,血清素在晚上也會比較低所以人在晚上才會多愁善感,這時候要讓自己的大腦慢下來才能降低焦慮感拉回血清素,所以常常會聽人家說去走走路跑跑步去散散心,因為我們在做這種運動的時候大腦是需要專心的,專心才可以把四處暴衝的大腦給停下來。

那如何在寫代碼的時候讓自己的大腦慢下來?我們有時候不會隨時站起來運動,這時候還是要利用其他身體元件部分去執行,既然我們不能用腳站起來運動就用手去『寫』下來,記住一定要寫而不是用電腦打字,當專心做這件事情的時候大腦就會慢下來了。

老師給的建議

先拿出一張紙。

  • 『寫』下自己的最終目標
  • 把這個目標轉變成有實際數字的數據目標

首先第一個『寫』下自己的最終目標不難解釋,就是像上面講的讓自己大腦慢下來

那把目標轉變成有實際數字的數據目標是什麼意思呢?

像這次的魔改大賽,寫下的目標可能是我要拿到前三名,但是這個目標很籠統又模糊,因為自己的大腦開始想我要css寫得很漂亮,我要js做哪幾個很不錯的功能,然後好了,看了一下別人的牛逼網站崩潰感直接衝進來,大腦又開始爆衝了。

所以停一下,想一下怎麼拿到前三名,最重要的是拿到『票數』,但票數跟程式碼是沒有直接關係的,那怎麼拿到更多票數呢?

思考一下VIP會員一張是10票,非VIP會員一張只等於1票,所以當然我們要主攻VIP會員,那也許我們不是真正做一個很屌的網站去吸引他們(別用自己的短處打別人長處),而是上社群網站分享一些技術文或心得去跟他們做交換。

再不行取得VIP的票,我們也可以放在自己的公眾號去拉票,怎麼樣都是往自己最清楚的小任務去前進達,成任務,而不是望著自己模糊的大目標讓自己的大腦高速空轉。

再來以自己網站為出發點的話,不要一直想著要坐著比別人牛逼的功能,因為自己實力不到就是不可能做出來的,再者其實功能牛逼並不一定可以讓別人喜歡,最重要的是看重使用者的體驗和操作。

什麼意思呢?

體驗上或許你可以針對整個網站的style和配色做調整,讓別人一進入這個網站就感覺到很舒服,也都可以快速清楚知道怎麼要使用這個網站。

操作上自己做的功能可不可以真的解決掉使用者的問題,譬如說做了一個查詢系統,但是資料庫裡面只有十筆資料給使用者查詢,這時候這個功能做得再漂亮或在牛逼都只是沒什麼用的東西而已。

這就是把模糊的大目標(想進入前三名),切成許多細小又清楚的小任務,我們一直不斷的做前進這個動作,不要一直讓自己的大腦處在高速空轉的暴衝狀態。

Nic 教你克服 DB

在rails101裡面我們很常下db migration這個指令,那到底這個指令是什麼東西呢?

其實就是在操作資料庫裡面的資料

第一如果我們不這樣去下達指令,而是直接去資料庫裡面篡改資料,一筆兩筆或許真的沒什麼,但如果今天有一千筆資料我們會改到崩潰,加上這樣的錯誤率會大幅提升,最後搞得非常麻煩。

第二我們這樣子下指令都會有紀錄,是誰新增了什麼,大幅提升專案的穩定性。

第三我們可以做到遠端許多裝置去協作一個專案,像是db:migrate就可以把自己本地端的專案同步為雲端最新的狀態。

常用指令:
1.rake
db:drop
db:create
db:migrate
db:reset
db:seed
db:migrate
db:rollback

rake是什麼??
我們可以直接收尋 rails rake 是什麼,老師說Google的能力是很重要的。

Schema綱要

1.改了沒有用(改他也沒意義)
2.記錄DB的版本號(像是DB的Git)
3.目前欄位狀況(像是log一樣可以列出來)

老師推薦一個gem是annotate,他可以直接在model裡面註解schema的東西。

我們直接在專案底下下rake db:migrate:status可以看到目前數據庫的進度和狀態。
up是執行到這一步down是還沒執行或者是退後過

譬如老師先新增了一個資料庫(model) 名稱是post title:string,此時執行rake db:migrate:status會出現down是因為數據庫並還沒有新增(更新),此時可以開atom去看自己的db文件看變化,我們下rake db:migrate後他會新增東西,然後再下rake db:migrate:status剛剛的down就變成up了,這時候如果又下rake db:rollback文件會有東西被刪除(最後一次新增的),而下rake db:migrate:status又會看到剛剛的up變為down了。

migrate可以操作資料庫,而schema是可以把資料庫git化,查看版本大綱,那我們不用去動schema,因為他是自動在記錄的,所以rake db:migrate:status才看得到變化。

剛剛講的annotate套件是什麼?
在Github上直接查詢他就有許多資訊。

先安裝後bundle install,最好是下只幫model生成的指令(他的Github上面有),這樣資料庫會直接生成註解,我們不用一直出來看schema的大綱。

觀念

讓數據庫保持在前進的狀態
除非不得已才退一步

退一步之後修改完馬上進一步,盡量不要退太多,如果是很久以前的錯誤不如前進一步去修改錯誤(修補的概念),例如到第十步的時候第二步有錯可以去使用rename功能,那如何使用老師叫我們上網查就有很多了!

關鍵字示範:rails migration rename

Q&A:

1.如何實現管理員權限,分高低級?
google can can can有套件

2.聽不懂

3.如何複製別人網站的JS效果?
JS不太能直接抄,很難debug,還要考慮到他們用什麼套件,再來不要求好先了解簡單的就好,現階段多使用小套件就好。

4.有沒有推薦css或html的教程?不然很容易遇到挫折
收尋 w3c html就很多了。

5.heroku更新數據會有問題?
heroku不給執行drop,要去找一下在上面的執行方法。

6.如何不同的電腦做同一個專案?
下載dropbox或者是雲端的東西直接把整包專案的資料夾丟進去。