[JavaScript]fadeIn & fadeOut with inline-block

現在jQuery幾乎已經成基本配備,簡單的網頁互動已經可以很輕鬆簡單的做一個基本的版本,這樣使用者在使用網頁的時候比較不會有頁面突然被刷新而不知所以然的疑慮,簡單的介紹fadeIn和fadeOut吧!

直接實作吧!

先做個最簡單的東西在html~

<div class="block"></div>
<div class="block2"></div>

再做一個簡單的css,注意我先把block2藏起來摟(display: none)!

body {
  text-align: center;
}
.block ,.block2{
  display: inline-block;
  margin-right: 30px;
  width: 100px;
  height: 100px;
  outline: 1px solid;
}
.block {
  background-color: blue;
}
.block2 {
  background-color: red;
  display: none;
}

接下來js實作fadeIn和fadeOut吧!

function block () {
  $('.block').fadeOut(function () {
    $('.block2').fadeIn();
  });
}
function blockTwo () {
  $('.block2').fadeOut(function () {
    $('.block').fadeIn();
  });
}

實作出來會發現block2並沒有置中,這是因為她的display被宣染成block而不是inline-clock了!!
這時候只要加一段jQuery的小東西.css()即可,所以我們修改上面的JavaScript如下:

function block () {
  $('.block').fadeOut(function () {
    $('.block2').fadeIn().css("display","inline-block");
  });
}
function blockTwo () {
  $('.block2').fadeOut(function () {
    $('.block').fadeIn();
  });
}

可以參考我的codepen

簡單認識fadeIn和fadeOut

在文件上他有兩個參數,一個是控制動畫的時間長短(單位是ms,預設400),另一個是執行完畢後要做的事情(function),兩個都是一樣的做法。

所以照著剛剛上面的範例條一個出來解釋的話:

$('.block2').fadeOut(3000, function () {
    $('.block').fadeIn(2000);
});

這樣就代表block2的fadeOut算整整三千毫秒執行完後才會執行後面的function,block的fadeIn會在兩千毫秒執行完畢。

參考網站

jQuery文件
stack overflow

自製semantic-ui有dimmer效果的modal

先了解原生ui範例和我們要做什麼

我們先來看看在semantic-ui的modal有什麼效果,請點連結裡按他的Run Code就有範例。

其實後面暗掉的布幕像是他們dimmer的效果,請點連結裡按他的Run Code就有範例。

所以我們要做的事情如下:
1. 有一個dimmer布幕。
2. 有一個浮在前面的modal(div等等)。

簡單實作

html 先做好簡單的三個東西:

  1. 當背景布幕的dimmer
  2. 啟動modal的button
  3. 要顯示的modal
    <div class="dimmer"></div>
    <button onclick="openModal()">open modal</button>
    <div class="modal">I'm modal<div>
    
    給他們css,先假裝page高度1000px,所以我直接先設body的height: 1000px;,接下來有兩件事情:
  4. 先把dimmer和modal用dislay: none;隱藏起來
  5. modal要在dimmer之前,並且dimmer要覆蓋著整個page,所以我們利用z-index做圖層分割
    body {
    height: 1000px;
    }
    .dimmer {
    display: none;
    position: relative;
    background-color: rgba(0, 0, 0, 0.53);
    width: 100%;
    height: 100%;
    position: fixed;
    z-index: 2;
    }
    .modal {
    display: none;
    position: relative;
    background-color: #fff;
    text-align: center;
    padding-top: 10px;
    border: 1px solid #fff;
    border-radius: 8px;
    width: 100px;
    height: 30px;
    margin: 0 auto;
    z-index: 3;
    }
    
    接著重頭戲JS利用delegate這個神奇的原生函示做出顯現modal和點擊dimmer就可以關掉modal的畫面:
    function openModal () {
    $('.dimmer').fadeIn(function () {
    $('.modal').fadeIn();
    });
    }
    $(document).ready(function() {
    $(document).delegate('body', 'click', function(event) {
    $('.modal').fadeOut(function () {
      $('.dimmer').fadeOut();
    });
    });
    $(document).delegate('button', 'click', function(event) {
    event.stopPropagation();
    });
    });
    
    初步認識一下delegate的觸發時間點是mousedown,如果想搞其他的變化了解這點很重要!! 還有z-index一定要搭配position: relative;或者是absolute;不可以使用預設的static! 這兩點注意好應該就可以實作出來想要的效果了,可以參考我直接在codepen上做的範例

[Vue2]使用semantic modal 遇到 at HTMLDivElement.invoker

我用的用法有點特別,算是硬改的所以引爆了一顆地雷,但是亂搞又自己救回來了XD

首先我們知道正常的方式是可行的:

<div id="clickme" @click="openModal">
    click me!
</div>
<div id="modal_signin" class="ui basic modal">
    Show modal
</div>
new Vue({
    el: '#clickme',
    methods: {
        openModal () {
             $('#modal_signin').modal('show');
        }
    }
});

錯誤fns.apply is not a function at HTMLDivElement.invoker

因某些因素所以我用的方法很奇耙,大概類似這樣:

<div id="clickme" @click="test">
    click me!
</div>
var obj = {
    el: '#clickme',
    data: {
        openModal: 'openModal'
        //注意一下這個data名稱,與第二個錯誤有關

    },
    methods {
        openModal () {
             $('#modal_signin').modal('show');
        }
    }
}
var temp = 
    '\<div>'+
        '\<div id="clickme" @click="openModal">'+
            'click me!'+
        '\</div>'+
        '\<div id="modal_signin" class="ui basic modal">'+
            'Show modal'+
        '\</div>'+
    '\</div>'
    
obj.template = temp;

new Vue(obj);

此時如果click則會報fns.apply is not a function at HTMLDivElement.invoker

錯誤openModal is not a function at click at HTMLDivElement.invoker

照著上面的範例,如果我把click改成@click="openModal()"則會報這個錯誤,但其實是method的名稱不能跟data的變數名稱重複,我也不知道發生了什麼事,總之趕快把問題紀錄下來~

最後解決方法

所以上面的代碼完全不動複製下來,只要改動一下:

<div id="clickme" @click="test">
    click me!
</div>
var obj = {
    el: '#clickme',
    data: {
        openModal: 'openModal'
        //注意一下這個data名稱,與第二個錯誤有關

    },
    methods {
        PleaseOpenModal () {
             $('#modal_signin').modal('show');
        }
    }
}
var temp = 
    '\<div>'+
        '\<div id="clickme" @click="PleaseOpenModal">'+
            'click me!'+
        '\</div>'+
        '\<div id="modal_signin" class="ui basic modal">'+
            'Show modal'+
        '\</div>'+
    '\</div>'
    
obj.template = temp;

new Vue(obj);

應該就行摟!

[CSS]用transition, before, after客製會滑動的按鈕 buttom

最近要試著做有動畫的按鈕,當hover的時候會有一個icon刷新的感覺,可以看Demo

先認識:before :after

每個class都有:before :after這兩個偽元素,你可以想像成創造了一個class="btn"後會變成:

.btn {}
.btn:before {}
.btn:after{}

不管css寫在哪都會有效果,值得注意的是:before和:after一定要有content這個屬性才有效果,而content是內文的意思,像是innerHtml
下列是同等效果:
正常元素

<style>
    .btn { color: red; };
</style>
<div class="btn">Btn</div>

偽元素

<style>
    .btn:before {
        content: 'Btn';
        color: red;
    };
</style>
<div class="btn"></div>

接下來進入主題

先做出有icon的原生還沒有動畫的buttom

<div class="btn">
  <p class="icon"></p>
  <span>Search</span>
</div>
.btn {//btn的容器
  text-align: center;
  width: 100px;
  height: 30px;
  margin: 1em;
  padding: 0px 10px 0px;
  border: 1px solid;
  border-radius: 20px;
  cursor: pointer;
}

.btn .icon {//會滑動的icon
  margin: 0px;
  padding: 0px;
  display: inline-block;
  position: relative;
  right: 14px;
  height: 29px;
  width: 29px;
  border: 1px solid;
  border-radius: 999px;
  background-color: #fff;
  z-index: 999;
}

.btn span {//一開始的內文
  opacity: 1;
  position: relative;
  bottom: 10px;
  right: 10px;
}

.btn:after {//icon滑動後更新的內文
  content: 'Go now';
  opacity: 0;//更新前是看不到的所以把他能見度設定0
  display: inline-block;
  position: relative;
  bottom: 32px;
  right: 10px;
}

接下來要注意的是transition(動畫)設定在初始的class裡面,所以我們更新後把CSS更新如下(記得我們還沒創造動畫唷!):

.btn {
  text-align: center;
  width: 100px;
  height: 30px;
  margin: 1em;
  padding: 0px 10px 0px;
  border: 1px solid;
  border-radius: 20px;
  cursor: pointer;
}

.btn .icon {//會動所以加上動畫屬性
  margin: 0px;
  padding: 0px;
  display: inline-block;
  position: relative;
  right: 14px;
  height: 29px;
  width: 29px;
  border: 1px solid;
  border-radius: 999px;
  background-color: #fff;
  z-index: 999;
  -webkit-transition: 0.6s;
  -moz-transition: 0.6s;
  -o-transition: 0.6s;
  transition: 0.6s;
}

.btn span {//會動(要消失)所以加上動畫屬性
  opacity: 1;
  position: relative;
  bottom: 10px;
  right: 10px;
  -webkit-transition: 0.6s;
  -moz-transition: 0.6s;
  -o-transition: 0.6s;
  transition: 0.6s;
}

.btn:after {//會動(要出現)所以加上動畫屬性
  content: 'Go now';
  opacity: 0;
  display: inline-block;
  position: relative;
  bottom: 32px;
  right: 10px;
  -webkit-transition: 0.6s;
  -moz-transition: 0.6s;
  -o-transition: 0.6s;
  transition: 0.6s;
}

最後我們觸發動畫是利用hover,所以把動畫的結果寫出來,css更新如下:

.btn {
  text-align: center;
  width: 100px;
  height: 30px;
  margin: 1em;
  padding: 0px 10px 0px;
  border: 1px solid;
  border-radius: 20px;
  cursor: pointer;
}

.btn .icon {
  margin: 0px;
  padding: 0px;
  display: inline-block;
  position: relative;
  right: 14px;
  height: 29px;
  width: 29px;
  border: 1px solid;
  border-radius: 999px;
  background-color: #fff;
  z-index: 999;
  -webkit-transition: 0.6s;
  -moz-transition: 0.6s;
  -o-transition: 0.6s;
  transition: 0.6s;
}

.btn:hover .icon {//讓icon向右邊跑
  right: -77px;
}

.btn span {
  opacity: 1;
  position: relative;
  bottom: 10px;
  right: 10px;
  -webkit-transition: 0.6s;
  -moz-transition: 0.6s;
  -o-transition: 0.6s;
  transition: 0.6s;
}

.btn:hover span {//讓初始內文消失
  opacity: 0;
}

.btn:after {
  content: 'Go now';
  opacity: 0;
  display: inline-block;
  position: relative;
  bottom: 32px;
  right: 10px;
  -webkit-transition: 0.6s;
  -moz-transition: 0.6s;
  -o-transition: 0.6s;
  transition: 0.6s;
}

.btn:hover::after {//讓更新內文出現
  opacity: 1;
}

這樣就大功告成囉!!!!

[JavaScript]localstorage存取物件(Object)和小地雷

工作上因為手機端的需求要直接在APP裡面開啟我這邊的html,但是在 <a> 這個tag無法使用_blank這個動作,他還是會切換到下一個網址造成回上一頁之後剛剛表單內的東西都被清空了,所以決定使用原生就有的localstorage(或者sessionstorage)來解決這個問題。

網路上可以查到的localstorage和sessionstorage寫法不只有一種,這邊就直接用sessionstorage下列簡單的例子當範例:

if ( window.sessionStorage["say"] === undefined ) {
    window.sessionStorage["say"] = 'Hello storage';
} else {
    var words = window.sessionStorage["say"];
}
console.log(words);
//第一次進入網頁會print undefined

//第二次進入網頁會print 'Hello storage'

記得window.sessionStorage["say"]內的say是自己命名的任意名稱,不是JS裡的變數~

但如果是有一堆變數要暫存的話,這時候就需要利用sessionStorage直接打包成一個物件暫存資料到cookie裡面,因為我不會想寫20行sessionStorage去存取資料的XD。

但遇到了點問題:

var myInfos = {
    name: 'Kurt',
    age: 25,
    isHandsome: 'Not really',
    humor: true
} 
if ( window.sessionStorage["profile"] === undefined ) {
    window.sessionStorage["profile"] = myInfos;
} else {
    var someBodyInfos = window.sessionStorage["profile"];
}
console.log(someBodyInfos);
//第一次進入網頁會print undefined

//第二次進入網頁會print '[Object Object]'

Yo~~~~照上面的例子難道我真的要為了一個有二十個變數的表單寫二十次sessionStorage了嗎?(搥地板)
別擔心,我們親愛的谷歌大神和stack overflow雙劍合併馬上解決了我的問題。

噹噹噹~使用Json格式存取

var myInfos = {
    name: 'Kurt',
    age: 25,
    isHandsome: 'Not really',
    humor: true
} 
if ( window.sessionStorage["profile"] === undefined ) {
    window.sessionStorage["profile"] = JSON.stringify(myInfos);
} else {
    var someBodyInfos = JSON.parse(window.sessionStorage["profile"]);
}
console.log(someBodyInfos);
//第一次進入網頁會print undefined

//第二次進入網頁會print

//{

//    name: 'Kurt',

//    age: 25,

//    isHandsome: 'Not really',

//    humor: true

//} 

這樣就能利用localstorage或sessionStorage存取打包好的物件甚至陣列摟!

還有個小地雷講下~再開發時我們愛用的無痕視窗是無法暫存資料到cookie的唷!那時做好後嚇了一跳勒XD。

最後如果想知道localstorage和sessionStorage有什麼差別的話可以參考這篇高級打字員的技術雲的部落格文章說明。

[Angular-1]angular debonse 和 ng驗證式的 undefined

遇到一種情況,想要在html用debonse延遲ng-change去判斷該model一些東西。

但其實有個小地雷是當model沒有通過html的angular驗證式的話model都會是undefined唷!!

我們可以直接先看到官方網站的範例,他裡面的條件設置為只能輸入數字,可以發現到當輸入的不是任意數字時input valid?會等於false之外,model是會顯示不出來的哦,因為此時的model會是undefined

所以如果要設計一個model同時搭配ng-parttern和ng事件的話絕對要注意model沒通過ng-parttern的話永遠會是undefined!

[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要如何設定。