如何发送KendoUI数据源的OData参数,以抽象的RESTful AngularJS数据工厂? [英] How to send KendoUI data source OData parameters to an abstract RESTful AngularJS data factory?

查看:451
本文介绍了如何发送KendoUI数据源的OData参数,以抽象的RESTful AngularJS数据工厂?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

前段时间,我安装一个抽象的数据工厂AngularJS,并需要就如何简化它的使用提示。我最初的IM pression,我会为每个实体,将来自AngularJS控制器被称为创造另一个下属工厂。原来它只是看起来太复杂,我想去掉中间的实体工厂( ContentTypesFactory ),并简单地直接从AngularJS控制器调用抽象工厂。

Some time ago, I setup an abstract data factory in AngularJS, and need a hint on how to simplify its use. I was initially under the impression that I would create another factory per entity that would be called from an AngularJS controller. Turns out it just looks too complicated and I would like to remove the intermediary entity factory (ContentTypesFactory), and simply call the abstract factory directly from the AngularJS controller.

在下面的例子中,我连线了KendoUI数据源。

In the following example I'm wiring up a KendoUI datasource.

AbstractRepository.js:

AbstractRepository.js:

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

    // we will inject the $http service as repository service
    // however we can later refactor this to use another service
    function abstractRepository(repositoryService, whichEntity, odataUrlBase) {
        //this.http = $http;
        this.http = repositoryService;
        this.whichEntity = whichEntity;
        this.odataUrlBase = odataUrlBase;
        this.route;
    }

    abstractRepository.prototype = {
        getList: function () {
            return this.http.get(this.odataUrlBase);
        },
        get: function (id) {
            return this.http.get(this.odataUrlBase + '/' + id);
        },
        insert: function (entity) {
            return this.http.post(this.odataUrlBase, entity);
        },
        update: function (entity) {
            return this.http.put(this.odataUrlBase + '/' + entity.ID, this.whichEntity);
        },
        remove: function (id) {
            return this.http.delete(this.odataUrlBase + '/' + id);
        }
    };

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

    }

    return abstractRepository;

}]);

ContentTypesFactory.js:

ContentTypesFactory.js:

/// <reference path="../Scripts/angular.min.js" />
/// <reference path="../app.js" />
/// <reference path="AbstractRepository.js" />

// each function returns a promise that can be wired up to callback functions by the caller
// the object returned from the factory is a singleton and can be reused by different controllers
app.factory('contentTypesRepository', ['$http', 'abstractRepository', function ($http, abstractRepository) {

    var odataUrlBase = '/odata/ContentTypes'
    var whichEntity = 'ContentTypes';

    function contentTypesRepository() {
        abstractRepository.call(this, $http, whichEntity, odataUrlBase);
    }

    abstractRepository.extend(contentTypesRepository);

    return new contentTypesRepository();

}]);

ContentTypesController.js:

ContentTypesController.js:

app.controller('contentTypesController', ['$scope', '$log', 'contentTypesRepository',
    function ($scope, $log, contentTypesFactory) {

        $scope.odataUrlBase = '/odata/ContentTypes';
        $scope.status;

        //
        // Grid
        //
        $scope.contentTypesDataSource = new kendo.data.HierarchicalDataSource({
            type: "odata",
            transport: {
                create: {
                    url: $scope.odataUrlBase
                },
                read: {
                    type: "GET",
                    url: $scope.odataUrlBase,
                    //function (data) {
                        // pass in the URL to the abstract factory                     
                    //},
                    dataType: "json"                                // the default result type is JSONP, but WebAPI does not support JSONP
                },
                update: {
                    contentType: "application/json",

                    url: function (data) {
                        return $scope.odataUrlBase + '(' + data.ContentTypesId + ')';
                    } . . . 

现在,删除提及ContentTypesFactory,我的新控制器code是这样的:

Now, removing the reference to ContentTypesFactory, my new controller code looks like this:

app.controller('contentTypesController', ['http', '$scope', '$log', 'abstractDataFactory',
    // the abstract data factory accepts controller type parameters for RESTful CRUD

    function ($scope, $log, abstractDataFactory) {
        //function ContentTypeController($scope) {

        var crudServiceBaseUrl = "/odata/ContentTypes";

        var odataUrlBase = '/odata/ContentTypes'
        var whichEntity = 'ContentTypes';

        // Pulled the following code from the ControlerTypesFactory, but not sure how to implement it in this ContentTypesController:

        //function contentTypesRepository() {
        //    abstractRepository.call(this, $http, whichEntity, odataUrlBase);
        //}

        //abstractRepository.extend(contentTypesRepository);
        //return new contentTypesRepository();

        $scope.greeting = 'Hola!';



        var dataSource = new kendo.data.DataSource({
            type: "odata",
            transport: {
                read: {
                    url: crudServiceBaseUrl,
                    dataType: "json"
                },
                update: { // PUT
                    url: function (data) {
                        console.log(data);
                        dataType: "json"
                        return crudServiceBaseUrl + "(" + data.ContentTypeId + ")";
                    },
                    error: function (e) {
                        console.log("error: " + e);
                    }
                }, . . .

我敢肯定,改变并不难,但我是相当新的角度。我怎么能这样组装起来,以便使用抽象的存储库,并寻找其它任何角度的最佳实践和命名建议?

I'm sure the change is not that difficult, but I'm fairly new to Angular. How can I wire this up so to use the abstract repository, and looking for any other Angular best-practices and naming suggestions?

推荐答案

目前今早重新审视,我相信我有一个可行的解决方案。

Taking a fresh look at this this morning, I believe I have a working solution.

再一次,我想要删除中介工厂抽象,并只有一个抽象数据获取工厂,我可以在参数传递直接从每个控制器。

Once again, I wanted to remove the intermediary factory abstraction, and have only one abstract data fetching factory that I could pass in parameters directly from from each controller.

$ HTTP 注射进厂这需要两个参数 whichEntity odataUrlBase ,并在实例化设置。工厂公开的方法,如的GetList(odataOptions)。这是一个需要与请求的查询字符串的一部分传承下去这些选项,并通过 $ HTTP 是这样做的 PARAMS

$http is injected into the factory which takes in two parameters whichEntity, odataUrlBase, and are set upon instantiation. The factory exposes methods like getList(odataOptions). It is these options that are required to to be passed along with the requests as part of the query string, and are done so through $http's params.

新抽象工厂注入控制器,随后用所需的参数实例

The new abstract factory is injected into the controller, then instantiated with the required parameters:

app.controller('contentTypeController', ['$scope', '$log', 'abstractFactory3',

    function ($scope, $log, abstractFactory3) {

        var dataFactory = new abstractFactory3("ContentType", "/odata/ContentType");

下面是新的抽象工厂:

app.factory('abstractFactory3', function ($http) {

    function abstractFactory3(whichEntity, odataUrlBase) {
        this.whichEntity = whichEntity;
        this.odataUrlBase = odataUrlBase;
    }

    abstractFactory3.prototype = {
        getList: function (odataOptions) {
            //var result = $http({               
            //    url: this.odataUrlBase,
            //    method: 'GET',
            //    params: odataParams
            //});

            return $http.get(this.odataUrlBase, {
                params: odataOptions
            });
        }
    };

    return abstractFactory3;
});

由于这是通过使用通过 kendo.data.DataSource ,我们要提取的OData参数:

Since this is being used through through a kendo.data.DataSource, we have to extract the OData parameters:

var odataParams = kendo.data.transports["odata"].parameterMap(options.data, "read");

在成功 GET ,我们传回数据源的选项的结果是:

Upon a successful get, we pass back the data source's options with the result:

    var dataSource = new kendo.data.DataSource({
        type: "odata",
        transport: {
            read:

                function (options) {
                    var odataParams = kendo.data.transports["odata"].parameterMap(options.data, "read");

                    dataFactory.getList(odataParams)
                        .success(function (result) {
                            options.success(result);
                        });

                    //$http({                           // // example of using $http directly ($http injection was removed from this controller, as this is now handled by the abstract data factory)
                    //    url: crudServiceBaseUrl,
                    //    method: 'GET',
                    //    params: odataParams
                    //})
                    //.success(function (result) {
                    //    options.success(result);
                    //});
                },  // update, create, destroy,  . . .

我意识到,在我原来的问题,控制器在使用剑道运输,而不是角的工厂,我不得不设置的事实。

I realize that in my original question, the controller was in fact using the Kendo transport, rather than the Angular factory that I had setup.

那么,我现在拥有的是:

So what I have now is:

角控制器(KendoUI数据源) - >角度数据工厂

angular controller (KendoUI datasource) -> angular data factory

我还改写了问题,以便更准确地反映整个问题是什么,并希望这是对别人的帮助。

I have also reworded the question in order to more-accurately reflect what the entire problem was, and hope this is of assistance to someone.

有一些其他的细微差别,如获取和传递数据的ID,对象JSON.stringification是最好的完整的解决方案中。希望以下帮助:

There are some other little nuances, like getting and passing data ID's, objects, JSON.stringification that are best shown in a full solution. Hopefully the following helps:

AngularJS抽象数据工厂​​:

AngularJS abstract data factory:

app.factory('abstractFactory3', function ($http) {

    function abstractFactory3(odataUrlBase) {
        this.odataUrlBase = odataUrlBase;
    }

    abstractFactory3.prototype = {
        getList: function (odataOptions) {
            //var result = $http({
            //    url: this.odataUrlBase,
            //    method: 'GET',
            //    params: odataParams
            //});

            return $http.get(this.odataUrlBase, {
                params: odataOptions
            });
        },
        get: function (id, odataOptions) {
            return $http.get(this.odataUrlBase + '/' + id, {
                params: odataOptions
            });
        },
        insert: function (data) {
            return $http.post(this.odataUrlBase, data);
        },
        update: function (id, data) {
            return $http.put(this.odataUrlBase + '(' + id + ')', data);
        },
        remove: function (id) {
            return $http.delete(this.odataUrlBase + '(' + id + ')');
        }
    };

    return abstractFactory3;
});

AngularJS控制器:

AngularJS Controller:

app.controller('contentTypeController', ['$scope', '$log', 'abstractFactory3',
    // the abstract data factory accepts controller type parameters for RESTful CRUD

    function ($scope, $log, abstractFactory3) {

        var dataFactory = new abstractFactory3("/odata/ContentType");

        var crudServiceBaseUrl = "/odata/ContentType";

        var dataSource = new kendo.data.DataSource({
            type: "odata",
            transport: {
                read:

                    function (options) {
                        var odataParams = kendo.data.transports["odata"].parameterMap(options.data, "read");

                        dataFactory.getList(odataParams)
                            .success(function (result) {
                                options.success(result);
                            })
                            .error (function (error) {
                                console.log("data error");
                            });

                    },
                update:
                    function (options) {
                        var data = options.data;
                        dataFactory.update(data.ContentTypeId, data)
                            .success(function (result) {
                                options.success(result);
                            })
                            .error(function (error) {
                                console.log("data error");
                            });
                },
                create:
                    function (options) {
                        var data = options.data;
                        data.ContentTypeId = "0";           // required for valid field data
                        dataFactory.insert(data)
                            .success(function (result) {
                                options.success(result);
                            })
                            .error(function (error) {
                                console.log("data error");
                            });
                },
                destroy: 
                    function (options) {
                        var data = options.data;
                        dataFactory.remove(data.ContentTypeId)
                            .success(function (result) {
                                options.success(result);
                            })
                            .error(function (error) {
                                console.log("data error");
                            });

                },
                parameterMap: function (options, type) {
                    // this is optional - if we need to remove any parameters (due to partial OData support in WebAPI
                    if (operation !== "read" && options.models) {
                        return JSON.stringify({ models: options });
                    }
                },

            },
            batch: false,
            pageSize: 10,
            serverPaging: true,
            change: function (e) {
                console.log("change: " + e.action);
                // do something with e
            },
            schema: {
                data: function (data) {
                    //console.log(data)
                    return data.value;
                },
                total: function (data) {
                    console.log("count: " + data["odata.count"]);
                    return data["odata.count"];
                },
                model: {
                    id: "ContentTypeId",
                    fields: {
                        ContentTypeId: { editable: false, nullable: true },
                        //UserId: {editable: false, nullable: false },
                        Description: { type: "string", validation: { required: true } },
                        //msrepl_tran_version: { type: "string", validation: { required: true } }
                    }
                }
            },
            error: function (e) {
                //var response = JSON.parse(e.responseText);
                var response = e.status;
                console.log(response);
            }

        });


        $("#grid").kendoGrid({
            dataSource: dataSource,
            pageable: true,
            height: 400,
            toolbar: ["create"],
            columns: [
                        { field: "ContentTypeId", editable: false, width: 90, title: "ID" },
                        { field: "Description", title: "Content Type" },
                        { command: ["edit", "destroy"] }
            ],
            editable: "inline"
        });


    }]);

这篇关于如何发送KendoUI数据源的OData参数,以抽象的RESTful AngularJS数据工厂?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆