2014年10月12日 星期日

Angularjs Cache Some Values

一個網站中可能會根據不同的需求來切換相關的子頁面,但若直接切換頁面在回來時將發現我們輸入到一半的某些值已清空,因此我們可以利用angularjs中的cacheFactory服務搭配routeProvider切換時的事件來儲存值,而頁面載入時則從cacheFactory中取出cache值。


一、$cacheFactory

從官方的API說明文件得知$cacheFactory可以儲存一些對象並存取,藉由key/value方式來操作。

var cache = $cacheFactory('cacheId');
cache.put("key", "value");
cache.get("key");

二、因此可以設計一個Factory的共用服務來儲存與取出。

(function(){
   angular.module('cacheFactoryModule',[])
        .factory('cacheFactory',function($cacheFactory){
           var cache = $cacheFactory('myCache');
            return{
                putData: function(key,values){
                    cache.put( key, values );
                },
                loadCacheData: function(key){
                    return cache.get(key);
                }
            }
        });
})();

三、設計index.html、main.html、detail.html,在index.html中使用一個<div>標籤,加入ng-view屬性來切換頁面,main.html則列出collection內容,detail.html則根據main.html列出的清單點選進細節頁面,藉由binding顯現出詳細資料,而此則以title簡單的模擬情境。

        (一)index.html
<div class="bg-success center" align="center" ng-view></div>
        (二)main.html已ng-repeat搭配link方式連結到詳細清單頁面。
<div>
<input type="text"
        ng-model="mainInputTextBox"
        placeholder="Search some value..."
        focus is-focus="true"
       />
<div class="playlist">
    <li ng-repeat="dataItem in mainDatas|filter:mainInputTextBox"><a href="#/details/{{$index}}"> {{dataItem.title}}</a></li>
</div>
<a class="btn btn-success" href="#/details/0" >Go to Detail</a>
</div>
         (三)detail.html則show出title,並加入preview、next兩個button來切換下一頁、前一頁。
<div>
<h3><span class="label label-default">{{mainDatas[whichId].title}}</span></h3>
<hr>
<input type="text"
       ng-model="detailInputTextBox"
       placeholder="Please Input somvalue..."
       focus is-focus="true"
        />

<a class="btn btn-success" href="#/main">Go to main.html</a>
<hr>

    <a class="btn btn-info" href="#/details/{{prevGuitar}}">Preview</a>
    <a class="btn btn-info" href="#/details/{{nextGuitar}}">Next</a>
</div>

四、設計cacheAppModule來進行頁面的切換,並加入autoFocus的自訂標籤。

(function(){
   angular.module('cacheAppModule',['ngRoute','cacheControllerModule','kendo.directives'])
        .config(['$routeProvider',function($routeProvider){
        $routeProvider.when('/main',{
            templateUrl: 'main.html',
            controller: 'mainController'
        }).when('/details/:detailsID',{
            templateUrl: 'detail.html',
            controller: 'detailController'
        }).otherwise({
            redirectTo: '/main'
        })
    }]).directive('focus',function($timeout){
           return{
               scope:{
                   isFocus: '='
               },
               link: function(scope,element){
                   scope.$watch('isFocus',function(value){
                       if (value){
                           $timeout(function(){
                               element[0].focus();
                           })
                       }
                   })
               }
           }
       });
})();

五、分別設計mainController及detailController且在兩個controller內加入頁面載入、頁面切換的事件監聽,進行存取cache值的方法。

(function () {
    angular.module('cacheControllerModule', ['ngRoute', 'cacheFactoryModule'])
        .controller('mainController', function (cacheFactory, $scope, $location) {
            $scope.nowPath = $location.path();
            var DataClass = function (title) {
                this.title = title;
            }
            $scope.mainDatas = [new DataClass('This is title for detail1'), new DataClass('This is title for detail2'), new DataClass('This is title for detail3')];
            $scope.$on('$viewContentLoaded', function () {
                $scope.onLoad()
            });
            $scope.$on('$routeChangeStart', function (event, next, current) {
                $scope.routeChangeStart()
            });
            $scope.onLoad = function () {
                var cacheDatas = cacheFactory.loadCacheData($scope.nowPath);
                if (!cacheDatas) return;
                $scope.mainInputTextBox = cacheDatas.mainInputTextBox;
            }
            $scope.routeChangeStart = function () {
                cacheFactory.putData($scope.nowPath, {'mainInputTextBox': $scope.mainInputTextBox});
                cacheFactory.putData('tmpParameter', $scope.mainDatas);
            }
        })
        .controller('detailController', function ($scope, $routeParams, $location, cacheFactory) {
            $scope.nowPath = $location.path();
            $scope.$on('$viewContentLoaded', function () {
                $scope.onLoad()
            });
            $scope.$on('$routeChangeStart', function () {
                $scope.routeChangeStart()
            });
            $scope.onLoad = function () {
                var cacheDatas = cacheFactory.loadCacheData($scope.nowPath);
                if (cacheDatas) $scope.detailInputTextBox = cacheDatas.detailInputTextBox;
                $scope.mainDatas = cacheFactory.loadCacheData('tmpParameter');
                $scope.whichId = parseInt($routeParams.detailsID);
                if ($routeParams.detailsID > 0)
                    $scope.prevGuitar = $scope.whichId - 1;//前一筆
                else
                    $scope.prevGuitar = $scope.mainDatas.length - 1;//小於0則設為最後一筆
                $scope.nextGuitar = ($scope.whichId + 1) % $scope.mainDatas.length;
            }
            $scope.routeChangeStart = function () {
                cacheFactory.putData($scope.nowPath, {'detailInputTextBox': $scope.detailInputTextBox});
            }
        });
})();
p.s存取的技巧則以path當key,然而value則為object方式在存放dataKey/dataValue,而dataKey為變數名稱、dataValue為變數值,取值時則以相同方式取之。

沒有留言:

張貼留言