【问题标题】:Angular service and pouchdbAngular 服务和 pouchdb
【发布时间】:2016-05-05 16:43:28
【问题描述】:

如何使用 angularjs 服务调用 pouchdb 并将数据返回给控制器?我一直在开发一个带有 pouchdb 的离子应用程序,用于本地存储。我有一个内置在控制器中的简单 crud 应用程序。现在我想开始将 pouchdb 调用移动到服务中。我无法从服务中取回数据。我将如何使用服务调用 pouchdb 来获取所有文档并将其返回给控制器?

【问题讨论】:

    标签: angularjs pouchdb


    【解决方案1】:

    我认为可以很好地用于 Angular 服务的一种策略是this one。它描述了一种保持内存数组与 PouchDB 的 allDocs() 的结果同步的方法。

    由于它是一个自动与 PouchDB 保持同步的数组,因此您只需在其上执行 ng-repeat,即可完成。 :)

    【讨论】:

    • Nolan,这不是真正的主题,但我正在寻找一个完整的、良好的最佳实践实现(一个完整的中小型开源或演示应用程序) angular-邮袋数据库。你能推荐一两个吗?
    【解决方案2】:

    虽然您的问题已有一年之久,但值得回答。

    您可能需要多个服务,即一个用于控制器,另一个用于后端数据库存储。例如在控制器中:

    (function () {
        'use strict';
    
        angular
            .module('app.services')
            .factory('db',db);
    
        db.$inject = ['$db'];
    
        function db($db) {
    
            var data = {};              // set up a data object to receive document(s)
    
            return {
                getDoc: getDoc,
                getList: getList,
                save: save,
                saveBatch: saveBatch
                };
    
    
            // get a single document using the id
            function getDoc(id) {
                $db.getDoc(id)
                    .then(
                        function onSuccess(doc) {
                            // success so update the view model
                            angular.extend(data,doc);                         // use angular.extend to shallow copy object so that it can be returned in full
                        },
                        function onError() {
                            // failure to get document                             
                        }
                    );
                return data;
            }
    
            // retrieve a group of documents where key is the prefix of the data you want
            function getList(key) {
                $db.getList(key).then(
                    function onSuccess(docs) {
                        // success so update the view model details
                        angular.forEach(docs.rows, function (value) {
                            this.push(value.doc);
                        }, data);
                        // now you can sort data or anything else you want to do with it
    
                    },
                    function onError() {
                        // no data found
                    }
                );
                return data;
            }
    
    
            // save a single viewItem
            function save(viewItem) {
                $db.update(viewItem).then(
                    function onSuccess() {                   
                        // success so update view model if required
                    },
                    function onError(e) {
                        console.log(e);         // unable to save
                    }    
                );    
            }
    
            // save an array of viewItems
            function saveBatch(viewItems) {
                $db.updateBatch(viewItems).then(
                    function onSuccess() {                   
                        // success so update the view model if required
                    },
                    function onError(e) {
                        console.log(e);         // unable to save
                    }    
                );    
            }
    
        }
    })();
    

    对于后端,类似这样:

    (function () {
        'use strict';
    
        angular
            .module('app.services')
            .factory('$db',$db);
    
        $db.$inject = ['$q'];
    
        function $db($q) {
    
            var db;
    
            return {
                setLocalDB: setLocalDB,
                update: update,
                updateBatch: updateBatch,
                getDoc: getDoc,
                getAllDocs: getAllDocs,
                getList: getList
            };
    
        // ------ DATABASE OPENING HANDLER(S) ------
    
            // set to any named database
           function setLocalDB(dbName) {
                db = new PouchDB(dbName);
                return db.info()
                    .catch(failedCheck());             // returns a promise to either work or fail
            }
    
            // return a rejection for a failure
            function failedCheck() {
                return $q.reject();
            }
    
        // ------ DOCUMENT HANDLING ------     
    
            // update document but if errors occur recurse qUpdate until either complete or retries exhausted
            function update(doc) {
                var counter = 0;
                return $q.when(qUpdate(doc,counter));
            }
    
            // this routine works for both new and existing documents
            function qUpdate(doc,counter) {
                return db.put(doc)
                    .then(function() {
                        console.log('success - new document');                 
                    })
                    .catch(function(e) { 
                        console.log(e);                     // not a new document so try as a revision of existing document using _id to find
                        return db.get(doc._id)
                            .then(function(origDoc) {
                                doc._rev = origDoc._rev;                    // get document revision _rev
                                return db.put(doc,doc._id,doc._rev)
                                    .then(function() {
                                        console.log('success - revision of document');
                                    })
                                    .catch(function(e){
                                        console.log(e);             // log error for failure
                                    });
                            })
                            .catch(function(e){
                                console.log(e);                     // log error before we take any other action
                                counter ++;                         // increment counter, so we can limit retries (5 by default)
                                if (counter< 5) {
                                    switch (e.status) {
                                        case 404:
                                            delete doc._rev;                        // remove revision information so we can see if this works
                                            return qUpdate(doc);                    // might be deleted so return revised document for retry                 
                                        case 409:
                                            return qUpdate(doc);                    // in conflict so try again
                                        default:
                                            try {
                                                throw new Error("cannot save: " + doc._id);     // cannot go any further so throw new error   
                                            } catch(err) {
                                                console.log(err);                               // log error for failure
                                            } 
                                    }
                                } else {
                                    try {
                                        throw new Error("cannot save" + doc._id);   // cannot go any further so throw new error 
                                    } catch(err) {
                                        console.log(err);                           // log error for failure
                                    } 
                                }
                            });    
                        });   
            }
    
            // update a document batch stored in an array
            function updateBatch(docs) {
                return $q.when(qUpdateBatch(docs));
            }
    
            // do the actual update of a batch
            function qUpdateBatch(docs) {
                db.bulkDocs(docs).then(function(res) {
                    for (var i=0; i < res.length; i++) {
                        if (res[i].status === 409) {
                            update(docs[i]);                 // in conflict so try this document separately
                        }
                    }
                }).catch(function(e){
                    console.log(e);                         // log error
                });  
            }
    
            // get the document as an angular promise and deal with it in host routine
            function getDoc(id)  {
                return $q.when(db.get(id));
            }
    
            // get all documents
            function getAllDocs() {
                return $q.when(db.allDocs({include_docs: true, attachments: false})); 
            }
    
            // get a batch of documents between a start and end key
            function getList(key) {
                return $q.when(db.allDocs({startkey: key, endkey: key + '\uffff', include_docs: true, attachments: false})); 
            }
        }
    })();
    

    在您的主控制器中,您需要设置数据库:

       $db.setLocalDB('yourDB'); 
    

    希望这就是您要找的吗?

    在我自己的数据服务模块中,我还有远程数据库、事件监听器、删除、同步、压缩、销毁等功能。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-04-30
      • 2016-10-21
      • 2017-05-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多