应用虚假数据源进行UI开发

时间:2014-05-07 01:19:12

标签: entity-framework angularjs breeze

我有一个带有Angular / Breeze客户端的Web应用程序调用Breeze Web API,它使用实体框架代码优先模型。我有一个datacontext(Angular服务)负责与服务器的所有通信。

我想将服务器开发与客户端开发完全分开,因此开发人员甚至不需要在他们的系统上安装.NET。我希望解决方案在创建假货时需要很少的编码,因为应用程序经常变化,我不想每次实现更改时都要重写伪造。我在数据库中有一堆测试数据,我想在客户端上提供。

实现这一目标的好方法(标准方式?)是什么?

2 个答案:

答案 0 :(得分:1)

只需创建模拟。如果您不想,您甚至不必进行RESTful调用,只需让您的服务决定是在服务器上启动还是从缓存中提取并在启动时在本地加载缓存 -

function loadMocks (manager) {
    var personMockOne = manager.createEntity('Person', { id: 1, firstName: 'John', lastName: 'Smith' });
    var companyMockOne = manager.createEntity('Company', { id: 1, name: 'Acme Inc.' });
    companyMockOne.employees.push(personMockOne);
}

http://pwkad.wordpress.com/2014/02/02/creating-mocks-with-breeze-js/

展开......

这样做需要一些额外的设置。我个人总是通过带参数的服务将我的查询与我的控制器/视图模型逻辑分开编写。一些示例参数总是类似于parametersforceRemote。我们的想法是,当您执行查询时,您可以决定是在本地命中服务器还是查询。一个简单的例子 -

function queryHereOrThere (manager, parameters, forceRemote) {
    var query = breeze.EntityQuery().from('EntityName').using(manager);
    query.where(parameters);

    if (!forceRemote) {
        query.executeQueryLocally();
    } else {
        query.executeQuery();
    }
}

答案 1 :(得分:1)

这是我目前的解决方案。

  1. 使用“单元测试”从服务器获取数据,该单元测试创​​建Breeze Web API控制器并使用它从数据库中收集breeze元数据和所有测试数据,然后将该数据写入{{1} }和testData.json

  2. 摘要将Breeze Entity Manager创建为Angular服务breezeMetadata.json

  3. 创建entityManager Angular服务,其中:1)创建实体管理器,2)覆盖EntityManager.executeQuery函数以始终使用本地版本,并且3)使用测试加载mgr数据。该服务的代码如下。

  4. fakeEntityManager服务中,使用datacontext服务有条件地注入真实或虚假的实体管理员。

  5. <强> datacontext.js

    $injector

    <强> fakeEntityManager.js

    angular.module('app').factory('datacontext', ['$injector','config', datacontext]);
    
    function datacontext($injector, config) {
    
        if (config.useLocalData === true) {
            var mgr = $injector.get('fakeEntityManager');
        } else var mgr = $injector.get('entityManager');
    
        ...
    

    如果不使用inlineCount查询,则无需覆盖executeQuery。您只需将以下属性添加到EntityManager构造函数的参数:

    (function() {
        'use strict';
    
        var serviceId = 'fakeEntityManager';
        angular.module('app').factory(serviceId, ['breeze', 'common', em]);
    
        function em(breeze, common) {
            var $q = common.$q;
            var mgr = getMgr();
            populateManager(["Projects", "People", "Organizations"]);
            return mgr;            
    
            function getMgr() {
                breeze.EntityManager.prototype.executeQuery = function(query) {
                    return $q.when(this.executeQueryLocally(query)).then(function (results) {
                        var data = {
                            results: results
                        };
                        if (query.inlineCountEnabled == true) data.inlineCount = results.length;
                        return data;
                    });
                };
                var metaData = < PASTE JSON HERE > 
                new breeze.ValidationOptions({ validateOnAttach: false }).setAsDefault();
                var metadataStore = new breeze.MetadataStore();
                metadataStore.importMetadata(metaData, true);
    
                return new breeze.EntityManager({
                    dataService: new breeze.DataService(
                        {
                            serviceName: "fakeApi",
                            hasServerMetadata: false // don't ask the server for metadata
                        }),
                    metadataStore: metadataStore
                });
            }
    
            function populateManager(resources) {
                var testData = < PASTE JSON HERE >;
                resources.forEach(function (resource) {
                    testData[resource].forEach(function (entity) {
                        mgr.createEntity(mgr.metadataStore.getEntityTypeNameForResourceName(resource), entity);
                    });
                });
            }
        }
    })();
    

    Todo:覆盖EntityManager.saveChanges()函数(或以某种方式配置实体管理器)以阻止对服务器的调用,同时仍允许在本地编辑和保存实体。