週末長知識: Facebook Platform Versioning

July 05, 2014
f8.png

angular-easyfb v1.1.0 released! 中提到是為了這個 Facebook 的 platform versioning 而做了一次更新,所以這個 platform versioning 到底是?

還記得日前有新聞說 Facebook 將推出匿名登入功能嗎? 第一次聽到這消息真是超驚為天人,畢竟目前大部分 “Connect with Facebook” 的運作模式就是靠著取得授權之後的 Facebook user ID 來進行諸如登入之類的操作,如果當真是 “anonymous” 的話,表示基本上就拿不到使用者的真實 Facebook user ID (必須「不能知道那名使用者是誰」),一定會造成許多 Facebook 相關的登入功能崩壞。

為了上述這個,以及往後到來的革命性的變動,Facebook 可能發覺以目前的 API 更動速率沒辦法有效的讓他們快速將新功能推向開發者們。與其每次都要告知開發者們「必須 migrate」的時間點,不如推出一個統一的機制省掉這些麻煩…

於是這個 platform versioning 應運而生。

Tip: 一般來說最大的版號有更動的時候,表示這兩個版本會發生不相容的情況。換句話說在 v1.0 運作正常的程式,在 v2.0 可能會壞得體無完膚

v1.0

就是我們在 2014/04/30 之前使用的 platform,2015/05/30 退役。 雖然可以透過附加 v1.0 在路徑裡的方式來使用 v1.0 的 API ,但這僅限於 2014/04/30 前建立的 Facebook app。

v2.0

2014/04/30 後建立的 Facebook app 一律採用 v2.0

改動超多,簡列如下:(詳見 changelog)

Read on 

angular-easyfb v1.1.0 released!

July 05, 2014

https://github.com/pc035860/angular-easyfb/releases/tag/v1.1.0

Facebook 似乎總是對開發者釋出善意,但我個人感覺實際上做的事情卻往往是不友善的…

幾個月前的 F8 大會上,Facebook 大動作想要讓他們的平台更迭系統化一點,終於推出了殺手級的改動 - platform versioning。於是很自然的也更新了一些原本 JavaScript SDK 的部分,這次 angular-easyfb 的更新基本上就是順應 Facebook 的野心…

續集: 週末長知識: Facebook Platform Versioning

Powerful $http in AngularJS

June 15, 2014

TL;DR

如果你怕 $http 會因為散布在各個 service 中而不小心送出多次同樣參數的 request,真的是白擔心了!

正文開始

今天本來心血來潮花了兩個小時想要做一個小 demo,來分享一下利用 promise 來避開在各個不同的 service 裡面對同一個 async task 套用一樣的參數而做重覆的 request 的問題。

不如直接看個上述情況最常碰到的 $http 範例。

angular.module('myApp', [])

.factory('common', function ($http) {
    return function () {
        return $http.get('api/common', {cache: true});
    };
})
.factory('taskA', function (common) {
    return function () {
        return common()
            .then(function () {
                // Do something
                return 'taskA';
            });
    };
})
.factory('taskB', function (common) {
    return function () {
        return common()
            .then(function () {
                // Do something
                return 'taskB';
            });
    };
})

.controller('MainCtrl', function (taskA, taskB, $timeout) {
    taskA();

    $timeout(function () {
        taskB();
    }, 100);
});

MainCtrl controller 裡面,不知道 taskAtaskB 究竟裡面做了什麼事的情況下,就會發生重覆對 api/commonGET request 的情況。

你說不是有加 {cache: true} 嗎? 但一般來說 cache 可以作用的前提是東西已經拿到了。在上面的範例裡,taskB 執行的時候有非常高的可能性 taskA 裡面的 request 還未完成,也就是說 cache 還是空的,於是就會在前一個 request 未完成的情況下再發一個一模一樣的 request。

範例: http://plnkr.co/edit/sXZYgC?p=preview

打開開發者工具來確認一下 XHR 的情況… powerful_http.png

竟然只有一個 request!!! 怎麼一回事!!!!???

Read on 

週末長知識: Range.getBoundingClientRect()

June 08, 2014

從本週開始推出「週末長知識」系列文章,希望能夠用簡潔俐落的方式(?)來一起長知識。

Range.getBoundingClientRect()

https://developer.mozilla.org/en-US/docs/Web/API/range.getBoundingClientRect

The Range.getBoundingClientRect() method returns a ClientRect object that bounds the contents of the range; this a rectangle enclosing the union of the bounding rectangles for all the elements in the range.

第一次看到這個東西是在偷看 Evernote Web Clipper 的 code 的時候… 當時覺得蠻新奇的就把它留在 gist 裡面,本週末因緣際會翻到這個 gist,就拿出來說嘴一番 lol

這個東西的做用講中文就是

基於被你選取的 Range object 內容所取得的 DOM 元素,返回 最小外接矩形

聽起來很抽象對吧.. 因為是「週末長知識」文章,我也不想說太多,直接來看 demo 吧!

Read on 

Faster paging in AngularJS

May 31, 2014

很多 AngularJS performance 相關的文章都是以 long lists 為主題來做提升,這篇的訴求比較不一樣 - 是 paging speed

本文所謂 paging speed ,指的是「由一頁換到另一頁所需要的速度」。 首先先來看看一個範例 AngularJS app 是如何切分資料以及換頁。

The usual way

這個範例用上了 UI Bootstrap 來做換頁輔助,它會幫你處理好總頁數跟一些換頁 UI (配合 Bootstrap) 的問題;基本上套用之後只要顧好利用 $scope.itemsPerPage 以及 $scope.currentPage 來將資料切片再餵給 ng-repeat 就可以輕鬆做出換頁的功能。

核心程式碼大概也就只有這樣:

// 目前頁面的變數有更動就更新 $scope.pagedData 的內容
$scope.$watch('currentPage', function (cp) {
  if (cp) {
    var slice = $scope.data.slice((cp - 1) * $scope.itemsPerPage, cp * $scope.itemsPerPage);
    // 為了保持使用原本的陣列,這邊用 angular.extend
    angular.extend($scope.pagedData, slice);
    $scope.pagedData.length = slice.length;
  }
});
<div class="row" ng-repeat="item in pagedData">
    <a href="" class="card" ng-controller="CardCtrl" ng-click="card.toggle()" ng-cloak>
        <img class="card__picture" ng-src="{{ item.picture }}" alt="{{ item.name }}" class="card__avatar">
        <div class="card__name">{{ item.name }}</div>
        <div class="card__phone">{{ item.phone }}</div>

        <!-- Prepare for what is going to happen -->
        <div ng-repeat="n in repeatList">
            <div class="card__about" ng-show="card.opened && $index == 0">{{ item.about }}</div>
            <div class="card__tags" ng-show="card.opened && $index == 0">
                <span class="card__tags__tag label label-info" ng-repeat="tag in item.tags track by $index">{{ tag }}</span>
            </div>
        </div>
    </a>
</div>

換頁速度的需求

除了去按下面那排 pagination 鈕之外,上面的範例還提供了額外的兩種可以操作換頁功能的方法(完全是我個人覺得按下面那排鈕來換頁好不方便):

  1. 鍵盤的 “left” 或 “right”
  2. 按著 “shift” 再滾動滑鼠滾輪

加上這兩個操作方法後,給 paging speed 增加了需多壓力,主因在於鍵盤(長按)與滑鼠滾輪的觸發頻率可以非常高,遠超過慢慢按那排 pagination 鈕。

你說用起來還是很順? 對,畢竟上面的範例給的壓力實在太小了。在真正會使用的具有較多功能的頁面裡,才能夠顯現出 paging speed 在這兩個特殊操作下的不足。

Read on