AngularJS: как вернуть многоразовый объект с фабрики?

В контроллере AngularJS у меня определено следующее:

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

    function ($scope, $log, abstractDataFactory, customFunctions) {

        var dataFactory = new abstractDataFactory("/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");
                            });
                  ...

Это все работает нормально. Однако я не хочу переопределять dataSource в другом контроллере для этого конкретного набора данных — ContentType и хотел бы его абстрагировать.

В результате я создал новый файл dataSourceFactory. Я не совсем понимаю, какая лучшая стратегия для реализации этого.

Я подумал, что хотел бы обновить dataSourceFactory так же, как я сделал abstractDataFactory из контроллера, и эти параметры передавались в abstractDataFactory из dataSourceFactory.

После внедрения нового dataSourceFactory в мой контроллер он будет возвращать различные источники данных в зависимости от вызова метода:

var dataSourceFactory = new dataSourceFactory("/odata/ContentType");
var dataSource = dataSourceFactory.contentType();  // .userDetails(), .someOtherData()...

Насколько я понимаю, фабрики Angular возвращают функции, поэтому я не думаю, что это именно то, что я ищу.

Пока вот моя нерабочая реализация:

Контроллер:

app.controller('contentTypeController', ['$scope', '$log', 'dataSourceFactory', 'customFunctions',

    function ($scope, $log, dataSourceFactory, customFunctions) {

        var dataSourceFactory = new dataSourceFactory("/odata/ContentType");
        var dataSource = dataSourceFactory.contentTypes();  // returns a function, rather than kendo.data.DataSource object
        ...

Источник данныхФабрика:

// factory to return datasources
app.factory('dataSourceFactory', function (abstractDataFactory) {

    function dataSourceFactory(odataUrlBase) {
        this.dataFactory = new abstractDataFactory(odataUrlBase);
    }

    dataSourceFactory.prototype = {
        contentTypes: function () {
            new kendo.data.DataSource({
                type: "odata",
                transport: {
                    read:

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

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

                        }
               },
                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);
                }
            })  // dataSource
        }  // contentTypes
    };

    return dataSourceFactory;

});

В итоге,

var dataSource = dataSourceFactory.contentTypes();  // returns a function, rather than kendo.data.DataSource object     

1) Источником данных должно быть значение нового объекта kendo.data.DataSource, а не функция. Поскольку фабрика возвращает функцию, как я могу использовать ее в своем контроллере, и правильно ли это делать, и если не предложения?

2) У меня будут различные источники данных, определенные в dataSourceFactory и используемые, как указано выше. Рекомендуется ли это (я собираюсь повторно использовать код, а не кучу отдельных фабрик для каждого источника данных), и если нет, предложения?


person ElHaix    schedule 12.03.2014    source источник
comment
Обычно сервисы представляют собой синглтоны, а фабрики создают экземпляры по требованию.   -  person Mike Cheel    schedule 12.03.2014
comment
Итак, моя первоначальная настройка, я считаю, верна - я создаю новый экземпляр dataSourceFactory по требованию с определенным значением oDataUrl.   -  person ElHaix    schedule 12.03.2014
comment
фабрики не должны возвращать функции, они могут возвращать все, что вы хотите   -  person doodeec    schedule 12.03.2014


Ответы (1)


Благодаря тонкому толчку из комментариев я смог понять это.

Первая проблема заключалась в том, что я фактически ничего не возвращал из вызова функции (отсутствовал оператор return из contentTypes:).

Во-вторых, мне пришлось определить dataFactory внутри dataSourceFactory, представляющего abstractDataFactory:

app.factory('dataSourceFactory', function (abstractDataFactory) {
    var dataFactory;

    function dataSourceFactory(odataUrlBase) {
        dataFactory = new abstractDataFactory(odataUrlBase);
    }

    dataSourceFactory.prototype = {
        contentTypes: function () {
            return new kendo.data.DataSource({ ... }...

Что мне до сих пор не ясно, так это то, что это хороший способ - вернуть все мои объекты источников данных одной фабрикой.

person ElHaix    schedule 12.03.2014