2014-05-12 4 views
5

AngularJS를 사용하여 작성한 단일 페이지 웹 앱이 있습니다. PouchDB를 사용하여 CouchDB 서버에 복제하면 제대로 작동합니다.AngularJS/PouchDB 앱이 cache.manifest 추가시 CouchDB와의 동기화를 중단합니다.

cache.manifest를 추가하여 오프라인에서 사용할 수 있도록 웹 페이지를 변환하려고하면 문제가 발생합니다. 갑자기 모든 복제 작업이 오프라인이나 온라인 작업 여부에 관계없이 오류를 발생시키고 작업을 중단합니다. 크롬에서

는 그냥 "GET ... myCouchIP/MYDB/_ 비표는 = CxVFIwnEJeGFcyoJ 그물 :: ERR_FAILED가?"라고 파이어 폭스에서

그것은 또한 오류가 발생하지만, 요청이 차단 된 것을 언급 - 가능 CORS를보십시오.

PouchDB 설정 페이지의 지침에 따라 원격 CouchDB에서 CORS를 사용할 수 있습니다. 게다가 cache.manifest를 사용하지 않는 동안 잘 작동합니다 (즉, 내 책상, 서버 및 VM 사이의 모든 다른 IP 주소에 만족합니다 - 프로토 타입이므로 현재로서는 도메인 이름이 없습니다).

덧붙여 말하자면, 현재로서는 어떤 종류의 인증도 사용하지 않습니다. 관리 파티가 적용됩니다.

그러면 cache.manifest를 추가 할 때 어떤 변경 사항이 적용됩니까? 단서는 감사하게 환영했다. 미리 감사드립니다.

는 app.js

var app = angular.module('Assets', ['assets.controllers', 'ngRoute']); 

app.config(['$routeProvider', function($routeProvider) { 
    $routeProvider. 
    when('/', { 
     controller: 'OverviewCtrl', 
     templateUrl: 'views/overview.html' 
    }). 
    when('/new', { 
     controller: 'NewMachineCtrl', 
     templateUrl: 'views/machineForm.html' 
    }). 
    otherwise({redirectTo: '/'}); 
}]); 

controller.js

var _control = angular.module('assets.controllers', ['assets.services']); 

_control.controller('OverviewCtrl', ['$scope', 'Machine', function($scope, Machine) { 
    var promise = Machine.getAll(); 

    promise.then(function(machineList) { 
     $scope.machines = machineList; 
    }, function(reason) { 
     alert('Machine list is empty: ' + reason); 
    }); 
}]); 

_control.controller('UpdateMachineCtrl', ['$scope', '$routeParams', 'Machine', 
              function($scope, $routeParams, Machine) { 
    $scope.title = "Update Installation Details"; 
    var promise = Machine.getSingle($routeParams.docId); 

    promise.then(function(machine) { 
     $scope.machine = machine; 
    }, function(reason) { 
     alert('Record could not be retrieved'); 
    }); 

    $scope.save = function() { 
     Machine.update($scope.machine); 
    }; 
}]); 

_control.controller('SyncCtrl', ['$scope', 'Machine', function($scope, Machine) { 
    $scope.syncDb = function() { 
     Machine.sync(); 
     Machine.checkConflicts(); 
    }; 

    $scope.checkCors = function() { 
     // Check CORS is supported 
     var corsCheck = function(method, url) { 
      var xhr = new XMLHttpRequest(); 

      if ("withCredentials" in xhr) { 
      // XHR for Chrome/Firefox/Opera/Safari. 
      xhr.open(method, url, true); 
      } else if (typeof XDomainRequest != "undefined") { 
      // XDomainRequest for IE. 
      xhr = new XDomainRequest(); 
      xhr.open(method, url); 
      } else { 
      // CORS not supported. 
      console.log('CORS not supported by browser'); 
      } 

      xhr.onload = function() { 
       console.log('Response from CORS ' + method + ' request to ' + url + ': ' + xhr.responseText); 
      }; 
      xhr.onerror = function() { 
       console.log('Error response from CORS ' + method + ' request to ' + url + ': ' + xhr.responseText); 
      }; 

      xhr.send(); 
     }; 

     var server = 'http://10.100.3.21:5984/ass_support'; 

     corsCheck('GET', server); 
     corsCheck('PUT', server); 
     corsCheck('POST', server); 
     corsCheck('HEAD', server); 
//  corsCheck('DELETE', server); 
    }; 
}]); 

service.js

var _service = angular.module('assets.services', []); 

_service.constant('dbConfig',{ 
    dbName: 'assets', 
    dbServer: 'http://myCouchServerIp:5984/' 
}); 

/** 
* Make PouchDB available in AngularJS. 
*/ 
_service.factory('$db', ['dbConfig', function(dbConfig) { 
    PouchDB.enableAllDbs = true; 
    var localDb = new PouchDB(dbConfig.dbName); 
    var remoteDb = dbConfig.dbServer + dbConfig.dbName; 
    var options = {live: true}; 
    var syncError = function() { 
     console.log('Problem encountered during database synchronisation'); 
    }; 

    console.log('Replicating from local to server'); 
    localDb.replicate.to(remoteDb, options, syncError); 

    console.log('Replicating from server back to local'); 
    localDb.replicate.from(remoteDb, options, syncError); 

    return localDb; 
}]); 

_service.factory('Machine', ['$q', '$db', '$rootScope', 'dbConfig', 
        function($q, $db, $rootScope, dbConfig) { 
    return { 
     update: function(machine) { 
      var delay = $q.defer(); 

      var doc = { 
       _id: machine._id, 
       _rev: machine._rev, 
       type: machine.type, 
       customer: machine.customer, 
       factory: machine.factory, 
       lineId: machine.lineId, 
       plcVersion: machine.plcVersion, 
       dateCreated: machine.dateCreated, 
       lastUpdated: new Date().toUTCString() 
      }; 

      $db.put(doc, function(error, response) { 
       $rootScope.$apply(function() { 
        if (error) { 
         console.log('Update failed: '); 
         console.log(error); 
         delay.reject(error); 
        } else { 
         console.log('Update succeeded: '); 
         console.log(response); 
         delay.resolve(response); 
        } 
       }); 
      }); 

      return delay.promise; 
     }, 
     getAll: function() { 
      var delay = $q.defer(); 

      var map = function(doc) { 
       if (doc.type === 'machine') { 
        emit([doc.customer, doc.factory], 
          { 
           _id: doc._id, 
           customer: doc.customer, 
           factory: doc.factory, 
           lineId: doc.lineId, 
           plcVersion: doc.plcVersion, 
          } 
        ); 
       } 
      }; 

      $db.query({map: map}, function(error, response) { 
       $rootScope.$apply(function() { 
        if (error) { 
         delay.reject(error); 
        } else { 
         console.log('Query retrieved ' + response.rows.length + ' rows'); 
         var queryResults = []; 

         // Create an array from the response 
         response.rows.forEach(function(row) { 
          queryResults.push(row.value); 
         }); 

         delay.resolve(queryResults); 
        } 
       }); 
      }); 

      return delay.promise; 
     }, 
     sync: function() { 
      var remoteDb = dbConfig.dbServer + dbConfig.dbName; 
      var options = {live: true}; 
      var syncError = function(error, changes) { 
       console.log('Problem encountered during database synchronisation'); 
       console.log(error); 
       console.log(changes); 
      }; 
      var syncSuccess = function(error, changes) { 
       console.log('Sync success'); 
       console.log(error); 
       console.log(changes); 
      }; 

      console.log('Replicating from local to server'); 
      $db.replicate.to(remoteDb, options, syncError). 
       on('error', syncError). 
       on('complete', syncSuccess); 

      console.log('Replicating from server back to local'); 
      $db.replicate.from(remoteDb, options, syncError);  
     } 
    }; 
}]); 

_service.factory('dbListener', ['$rootScope', '$db', function($rootScope, $db) { 
    console.log('Registering a onChange listener'); 
    $db.info(function(error, response) { 
     $db.changes({ 
      since: response.update_seq, 
      live: true, 
     }).on('change', function() { 
      console.log('Change detected by the dbListener'); 
      // TODO work out why this never happens 
     }); 
    }); 
}]); 

cache.manifest

CACHE MANIFEST 

# views 
views/machineForm.html 
views/overview.html 

# scripts 
scripts/vendor/pouchdb-2.2.0.min.js 
scripts/vendor/angular-1.2.16.min.js 
scripts/vendor/angular-route-1.2.16.min.js 

scripts/app.js 
scripts/controllers/controller.js 
scripts/services/service.js 

index.html을

<!DOCTYPE html> 
<html lang="en" manifest="cache.manifest" data-ng-app="Assets"> 
<head> 
<meta charset="UTF-8"> 
<meta name="viewport" content="width=device-width, initial-scale=1"> 
<title>Asset Management</title> 

<script src="scripts/vendor/angular-1.2.16.min.js" type="text/javascript"></script> 
<script src="scripts/vendor/angular-route-1.2.16.min.js" type="text/javascript></script> 
<script src="scripts/vendor/pouchdb-2.2.0.min.js" type="text/javascript"></script> 

<script src="scripts/app.js" type="text/javascript"></script> 
<script src="scripts/services/service.js" type="text/javascript"></script> 
<script src="scripts/controllers/controller.js" type="text/javascript"></script> 
</head> 
<body> 
    <div id="content"> 
    <nav class="sidebar"> 
    <h3>Options</h3> 
    <div> 
     <a class="active" data-ng-href="#/">Overview</a> 
     <a data-ng-href="#" data-ng-controller="SyncCtrl" data-ng-click="syncDb()">Synchronise</a> 
     <a data-ng-href="" data-ng-controller="SyncCtrl" data-ng-click="checkCors()">Check CORS</a> 
    </div> 
    </nav> 

    <section class="main"> 
     <div data-ng-view></div> 
    </section> 
    </div> 
</body> 
</html> 

overview.html

<h3>Installation Overview</h3> 
<table> 
    <tr> 
     <th>Customer</th> 
     <th>Factory</th> 
     <th>Line Id</th> 
     <th>PLC Version</th> 
    </tr> 
    <tr data-ng-repeat="machine in machines"> 
     <td>{{machine.customer}}</td> 
     <td>{{machine.factory}}</td> 
     <td><a data-ng-href="#/view/{{machine._id}}">{{machine.lineId}}</a></td> 
     <td>{{machine.plcVersion}}</td> 
    </tr> 
</table> 

machineForm.html

<h3>{{title}}</h3> 
<form name="machineForm" data-ng-submit="save()"> 
    <div> 
    <label for="customer">Customer:</label> 
<div><input data-ng-model="machine.customer" id="customer" required></div> 
    </div> 

    <div> 
    <label for="factory">Factory:</label> 
    <div><input data-ng-model="machine.factory" id="factory" required></div> 
    </div> 

    <div> 
<label for="lineId">Line ID:</label> 
    <div><input data-ng-model="machine.lineId" id="lineId" required></div> 
    </div> 

    <div> 
<label for="plcVersion">PLC Version:</label> 
    <div><input data-ng-model="machine.plcVersion" id="plcVersion"></div> 
    </div> 

    <div><button data-ng-disabled="machineForm.$invalid">Save</button></div> 
</form> 
+0

jsfiddle 또는 이것을 재현 할 수있는 것이 있으면 정말 도움이 될 것입니다. [PouchDB GitHub] (https://github.com/pouchdb/pouchdb/issues) 페이지에서 문제를 제기하십시오. – nlawson

+0

jsfiddle을 사용하지 않았지만 공개적으로 사용할 수있는 데이터베이스 서버가 없어서 작동하지 않을 것이라고 생각합니다. 가장 관련성이 높은 코드를 게시했습니다. 미안 게시물이 지금 미쳤다면. –

답변

10

이에 cache.manifest 파일을 변경해보십시오 :

CACHE MANIFEST 

CACHE: 
# views 
views/machineForm.html 
views/overview.html 

# scripts 
scripts/vendor/pouchdb-2.2.0.min.js 
scripts/vendor/angular-1.2.16.min.js 
scripts/vendor/angular-route-1.2.16.min.js 

scripts/app.js 
scripts/controllers/controller.js 
scripts/services/service.js 

NETWORK: 
* 

매니페스트 파일을 사용하여, 모든 캐시되지 않은 리소스를 온라인 상태에서도, 캐시 된 페이지에 실패합니다. NETWORK 섹션은 캐시되지 않은 리소스에 대한 요청을 허용하도록 브라우저에 지시합니다 (물론 오프라인 일 때 계속 실패합니다).

+1

그건 하나 였어. 지금 일을 확인했습니다. 많은 감사 –