当前位置: 首页 > 面试题库 >

是否可以以良好的形式重用Angular中的相同数据工厂?

锺离霖
2023-03-14
问题内容

我正在寻找Angular的CRUD通用工厂(我目前更喜欢使用服务):

app.factory('dataFactory', ['$http', function ($http) {
    var urlBase = '/odata/ContentTypes';

    // The _object_ defined in the factory is returned to the caller, rather than as with a service,
    // where the _function_ defined in the service is returned to the caller
    var dataFactory = {};

    dataFactory.getContentTypes = function () {
        var contentTypes = $http.get(urlBase);

        return contentTypes;
    };

    dataFactory.getContentType = function (id) {
        return $http.get(urlBase + '/' + id);
    };

    dataFactory.insertContentType = function (contentType) {
        return $http.post(urlBase, contentType);
    };

    dataFactory.updateContentType = function (contentType) {
        return $http.put(urlBase + '/' + contentType.ID, contentType);
    }

    dataFactory.deleteContentType = function (id) {
        return $http.delete(urlBase + '/' + id);
    }


    // to traverse navigation properties
    //dataFactory.getUserFromContentTypeId = function (id) {
    //    return $http.get(urlBase + '/' + id + '/user');
    //}


    //dataFactory.getOrders = function (id) {
    //    return $http.get(urlBase + '/' + id + '/orders');
    //};


    return dataFactory;

}]);

对于我所有的实体,此代码将大致相同。是否可以注入实体名称(或相应的RESTful路径),如果可以,可以将其视为局部类,如果需要其他承诺(例如遍历导航属性),也可以注入它们?

如果可以使用Angular做到这一点,有人可以发布一些示例吗?


问题答案:

就我个人而言,我希望代码保持干燥状态,并且发现,如果在服务器API上保持通用约定,则可以使用基本工厂/存储库/类或任何您想调用的名称走很长一段路。我在AngularJs中实现此目标的方法是使用AngularJs工厂,该工厂返回基本存储库类,即工厂返回带有原型定义而不是对象实例的html" target="_blank">html" target="_blank">javascript类函数,我称之为abstractRepository。然后,针对每个资源,为该典型资源从原型继承的具体资源创建一个具体的存储库abstractRepository,因此我继承了所有共享/基本功能,abstractRepository并为具体存储库定义了任何资源特定的功能。

我认为一个例子会更清楚。假设您的服务器API使用以下URL约定(我不是最纯REST的人,所以我们将把约定留给您要实现的任何约定):

GET  -> /{resource}?listQueryString     // Return resource list
GET  -> /{resource}/{id}                // Return single resource
GET  -> /{resource}/{id}/{resource}view // Return display representation of resource
PUT  -> /{resource}/{id}                // Update existing resource
POST -> /{resource}/                    // Create new resource
etc.

我个人使用Restangular,因此以下示例基于该示例,但是您应该可以轻松地将其调整为$http$resource

abstractRepository

app.factory('abstractRepository', [function () {

    function abstractRepository(restangular, route) {
        this.restangular = restangular;
        this.route = route;
    }

    abstractRepository.prototype = {
        getList: function (params) {
            return this.restangular.all(this.route).getList(params);
        },
        get: function (id) {
            return this.restangular.one(this.route, id).get();
        },
        getView: function (id) {
            return this.restangular.one(this.route, id).one(this.route + 'view').get();
        },
        update: function (updatedResource) {
            return updatedResource.put();
        },
        create: function (newResource) {
            return this.restangular.all(this.route).post(newResource);
        }
        // etc.
    };

    abstractRepository.extend = function (repository) {
        repository.prototype = Object.create(abstractRepository.prototype);
        repository.prototype.constructor = repository;
    };

    return abstractRepository;
}]);

具体的存储库,让我们以客户为例:

app.factory('customerRepository', ['Restangular', 'abstractRepository', function (restangular, abstractRepository) {

    function customerRepository() {
        abstractRepository.call(this, restangular, 'customers');
    }

    abstractRepository.extend(customerRepository);
    return new customerRepository();
}]);

然后在您的控制器中注入customerRepository

app.controller('CustomerController', ['$scope', 'customerRepository', function($scope, customerRepository) {
    // Use your customerRepository
}]);

如果使用这种基本存储库模式,您会发现大多数CRUD控制器也将共享许多通用代码,因此我通常会创建一个基本CRUD控制器,我的控制器使用继承该基本CRUD控制器$injector.invoke,但我将保留以下示例这超出了这个问题的范围。



 类似资料:
  • 问题内容: 目标:实施标准的“设置” GUI窗口。类别位于 ListView左侧,而相应选项位于Pane右侧。 (请忽略具有重复类别的明显错误;仍在处理) 在此处输入图片说明 我有一个用于整体“设置”窗口的主窗口,其中包含 ListView带有所有类别的设置。窗口的右侧 具有AnchorPane, 当从列表中选择一个类别时,用于为每个类别加载单独的FXML文件。 当用户选择类别时,我需要他们能够编

  • 我有一个用于总体设置窗口的主窗口,其中包含一个和所有设置类别。窗口的右侧有一个,用于在从列表中选择每个类别时为每个类别加载单独的FXML文件。 当一个用户选择一个类别,我需要他们能够编辑右边的设置,切换到另一个类别,并作出更多的改变。然而,如果他们回到第一类,那里所做的改变会持续下去。 我的明显问题是,每次用户更改类别时,都会重新加载FXML文件和控制器,将其中的所有控件重置为它们的默认值。 研究

  • 问题内容: 我已经编写了一个JavaScript函数,该函数使用XmlHttpRequest异步调用Web服务。我被要求使此功能在呈现页面之前完成其工作。 我以为我可以使AJAX请求同步,但是我不希望这使页面挂起太长-如果没有收到响应,我想在1秒后中止请求。 是否可以中止同步的XmlHttpRequest? 问题答案: 您不能: http://www.hunlock.com/blogs/Snipp

  • 问题内容: 我有一个网站,所有请求都通过(无提示)被无提示地重定向到,然后PHP用于显示正确的页面(通过解析)。 我想知道是否也可以将POST数据提交到假地址? 我目前有这样的表格… 我的规则是 我的支票工作正常。 但是,这似乎删除了应该发送给它的所有POST数据。 有没有办法保留帖子数据?我不想使用GET,因为它不能发送太多信息,尽管使用简单的查询表可能不会出现问题。 这是我重定向到的 问题答案

  • 问题内容: 如果您的类路径中有两个jar,其中包含同一个类的不同版本,则类路径的顺序就变得至关重要。 我正在寻找一种可以检测并标记给定类路径或文件夹集中的潜在冲突的工具。 当然可以启动一个脚本: 稍后使用一些巧妙的sort / uniq / diff / grep / awk很有潜力,但是我想知道是否有人知道任何现有的解决方案。 问题答案: JBoss 的Tattletale工具是另一个候选者:“

  • 我已经创建了一个按钮数组(),我想为数组中的所有按钮添加相同的操作侦听器,而不是逐个添加它们。 想象一下,每次我点击屏幕上显示的一个按钮,它就会在数组中打印出该按钮的索引。