Single Page Blog with AngularJS

jopen 8年前發布 | 15K 次閱讀 Web框架 angularjs

今天這篇博客的主題是Single-page blog with AugularJS,也就是說,用AngualrJS做一個Single-page app(SPA),并用在博客系統上。如果乃是個典型的有代碼堅決不看文檔的童鞋,可以直接跳轉 這里Single Page Blog 看代碼。對于這個topic,我覺得有責任對讀者朋友們說點什么。我一定不是第一個做這件事的人,我肯定也不會是最后一個,但我還是要把自己的切身經歷講一講,盡可能地讓部分讀者知道,因為這些open source tool/library的存在,開發一個你想象中的產品變得如此容易。

前因

前段日子我和sneezry吐槽,我們組這次re-arch打算純用AngularJS做一個SPA。是的你沒看錯,龐大臃腫如我司現在也突然開始更大限度地鼓勵開發擁抱新的(或者叫 外面的)技術,就像了迎來了改革開放。沒有一丁點兒的.NET code,換做誰都是要有顧慮的,可以想象,這樣一個決定在公司內引起多大的波瀾。sneezry甚至還寫了這樣一篇 博客 來吐槽我們這群猿始人。

一個月過去了,產品漸漸成型。我和大小伙伴們驚奇地發現,prototype的效果比想象中好非常多,performance問題也不算大。周五看完他們的demo,被小小震撼的我決定自己也來試試AngularJS。

Single-Page App

簡單來說,一個SPA就是動態地加載資源,把所有的功能都在單個頁面實現,用戶訪問不同的功能時不需要頁面的跳轉,就像你使用大部分桌面應用一樣。這里我們只是管中窺豹說到SPA,我第一個想到的,其實是Sneezry的博客系統Hooloo,無論是查看博客列表還是閱讀文章,都不用離開當前頁面。不過Sneezry的大神比較土豪,沒有使用什么庫,自己拿JS手寫的。我等學渣肯定學不來,我就來看看用AngularJS該怎么達到相同的目的。

View Engine

作為一個足夠簡陋的博客,需要且只要兩種頁面,第一個是blog list,第二個就是article content。只要有一個section能夠動態加載頁面,就大功告成了。我雖然沒有一丁點兒AngularJS的知識,但是我知道在Asp.NET里面是這么做的:

<div role="main">
        @RenderBody()
</div>

于是我到famous website上查了一把,發現AngularJS的做法也是非常的類似:

<html data-ng-app="SinglePageBlogApp">
    <div data-ng-view=""></div>
</html>

知道把動態的page往哪兒塞,任務已經剛完成了一半,剩下的另一半就是怎么往里面塞呢?

Routing

用一個小學生都能懂的話來解釋,要訪問不同的頁面,輸入不同的url就行了。回到我熟悉的Asp.NET,我知道,通過訪問不同的view,Asp.NET的view engine會把對應的html渲染后扔回去(也就是RenderBody)。殊途同歸,我想AngularJS的做法肯定不會差太遠。稍微調整了幾個搜索關鍵詞后,我找到了答案:

app.config(function ($routeProvider) {

    $routeProvider.when("/home", {
        controller: "BlogController",
        templateUrl: "app/views/home.html"
    });
      $routeProvider.when("/:year/:month/:day/:name", {
        controller: "EntryController",
        templateUrl: "app/views/entry.html"
    });
    $routeProvider.otherwise({ redirectTo: "/home" });
});

上面的code簡直就像普通話一樣通俗易懂。引入一個名叫ngRoute的module后,我可以定義不同url pattern對應的頁面,比如訪問”/home”,就會得到”home.html”;訪問”2014/04/20/SinglePageBlog”,會得到”entry.html”。

不過”home.html”依然只是static page,我們肯定不希望每次寫了一篇新的文章,我都去更新”home.html”中的blog list。這樣雖然夠靜態夠環保,可是真的大丈夫嗎?

好在Angular能夠允許我們定義怎么渲染頁面,這也就是上面代碼中controller的作用,通過自己定義controller,能夠動態的創建頁面。下面我們來看看我是怎么做的。

home.html它長這樣,雖然有點磕磣:

<div>
<ul>
    <li ng-repeat="blog in blogList">
        <a ng-click="selectBlog(blog)" >{ { blog["name"] } }</a>
    </li>
</ul>
<hr>
</div>

ng-repeat的作用是輪詢 blogList 里的blog object,為每個blog創建一個對應的 <li> , { { blog["name"] } } 則是訪問這個blog對象的field:name。定義完這個動態的html,下面我們來看看負責渲染的controller BlogController.js

app.controller('BlogController', function($scope, $http, $log, $window, blogEntryService) {
        $scope.blogList = [];
        $http({method: 'GET', url: 'https://api.github.com/repos/rebornix/rebornix.github.io/contents/_posts'}).
            success(function(data, status, headers, config) {
                    var alldata = data.reverse();
                    $scope.blogList = [];
                    alldata.forEach(function(entry) {
                        var suffix = "md";
                        if (entry["name"].indexOf(suffix, entry["name"].length - suffix.length) !== -1){
                            $scope.blogList.push(entry);
                        }
                    });
                });
            });
        $scope.currentBlog= $scope.blogList[0];

        $scope.selectBlog = function(blog) {
            blogEntryService.setBlogEntry(blog);
            params = blog["name"].split('-');
            $window.location.href = "#/" + params[0] + "/" + params[1] + "/" + params[2] + "/" + params[3].replace(".md", "");
        }
});

讀者可能并不知道上面代碼里 $scope $http 的含義,但不影響我們理解這段代碼的作用。我對 https://api.github.com/repos/rebornix/rebornix.github.io/contents/_posts Get了一把,獲得了我寫過的文章的列表,然后賦值給了blogList,因為blogList是一個list,我們最終能夠在 home.html 里對它做了一個輪詢 ng-repeat="blog in blogList" ,記得嗎?

通過相同的方式,我給”entry.html”寫了一個controller用來顯示blog content。

一個簡易的,不需要任何backend,不需要任何環境(php,ror,django,etc)支持的博客系統就完成啦

后果

就這樣,寫了不到一百行代碼(如果我把html也當代碼的話),我就已經實現了一個single-page blog,詳情可見 spblog.github.io ,你也可以fork 源代碼 然后修改,code實在是少得很,基本是在寫CSS與HTML。而我只是對angularjs的view-engine和routing有了些許的了解。從學習angularJS到最終完成不到半天,這其中還夾雜著洗衣做飯陪女王大人看電視。

當然對于一個功能完備的博客來說,還有很多坑要踩,比如博文被Google收錄的問題,這些在Sneezry介紹 Hooloo的博客 里也都有提到(不得不佩服Sneezry,這貨幾乎是完成了和AngularJS相似的功能,造輪子萬歲!),但我就不繼續了。畢竟,我的目的并不是拿AngularJS再造一個Hooloo。

作為一個吃軟飯的.NET程序員,我只是突然意識到,如果把AngularJS(或者knockout,whatever)和Asp.NET結合在一起,能夠創造出無與倫比的Single-page Blog Application。To be continued…

來自: http://rebornix.com/海上日志/2014/04/20/SinglePageBlogWithAngularJS/

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!