AngularJS модулей + импорт Webpack + ES6 - проблема с внедрением зависимостей и согласованным порядком - PullRequest
0 голосов
/ 07 января 2020

Краткое описание проблемы

Я перевожу старое приложение AngularJS для использования Webpack и делю его на три части, которые я хочу представить в виде AngularJS модулей:

  • ср c -ts-admin
  • ср c -ts-common
  • ср c -ts-store

Например, я бы хотел, чтобы 'sr c -ts-admin' использовал сервисы из 'sr c -ts-common', но, к сожалению, веб-пакет объединяет файлы в неправильном порядке для AngularJS Внедрение зависимостей, так что я получаю ошибки типа ..

Error: "[$injector:unpr] Unknown provider: filterServiceProvider <- filterService <- initializerService

.., где initializerService - это сервис от sr c -ts-admin и filterService от sr c -ts-common. Суть проблемы заключается в том, что модуль

  • ("ADMIN"). Service ("initializerService") выполняется до того, как модуль
  • ("COMMON) .service (" filterService ")

.. хотя я не могу определить проблему в зависимостях.

Обзор файла

sr c -ts-admin: app.ts

Это точка входа в веб-пакет, однако она не столь интересна. При маршрутизации приложения будет вызываться app.initializer.ts.

import angular from 'angular';
import { appModule } from './app.module';

sr c -ts-admin: app.module.ts

import angular from 'angular';
import commonModuleName from '../src-ts-common/common.module';

var modulezz;
modulezz = [commonModuleName,'ngRoute', 'ui.router', 'ui.multiselect', 'ui.bootstrap', 'ui.bootstrap-slider', 'ui.bootstrap.buttons', 'duScroll',
            'ngMessages', 'colorpicker.module', 'angular-bind-html-compile', 'pascalprecht.translate'];

export var appModule = angular.module("ADMIN", modulezz);
export default appModule.name;

sr c -ts-admin: app.initializer.ts

import angular from "angular";
import appModuleName from "./app.module";
import { filterService } from "../src-ts-common/service/filter-service-model";

export class InitializerController {
    static $inject = ...etc...
    constructor(...etc...) {

    /* THIS IS KICKED OFF BY AN ANGULAR ROUTE, THIS KICKS OFF THE InitializerController BELOW */

    }
}
angular.module(appModuleName).controller("initializerController", InitializerController);

export class InitializerService {
    static $inject = ["$stateParams", "$window", "$timeout", "filterService", ...etc...];
    constructor(private $stateParams, private $window, private $timeout, private filterService: filterService, ...etc...) {

        /* THIS IS WHERE THE DEPENDENCY INJECTION FAILS */

    }
}
angular.module(appModuleName).service("initializerService", InitializerService);

sr c -ts-common: common.module.ts

import angular from 'angular';
export default angular.module("COMMON",[]).name;

sr c -ts-common: filter.service.ts

import angular from "angular";
import commonModuleName from '../common.module';

export class filterService {
    static $inject = [];
    constructor() {
    /* ...simplified... */
    }
}
angular.module(commonModuleName).service("filterService", filterService);

Мои мысли

Я получаю ошибку ..

Error: "[$injector:unpr] Unknown provider: filterServiceProvider <- filterService <- initializerService

... который указывает мне, что app.initializer.ts выполняется перед filter.service.ts, хотя он импортирует этот файл.

Видите ли вы какие-либо грубые ошибки, которые я сделал? структура AngularJS + Модуль Webpack импортирует nd cut files?

--- Решение (Обновить!) ---

Благодаря { ссылка } Я смог решить мою проблему. Шаблон, который я должен был использовать, был инициализировать модули angular (например, angular.module(commonModuleName).service("filterService", filterService);) в файлах app.module.ts и common.module.ts, а НЕ вместе с их реализациями классов.

Здесь исправленные файлы:

ср c -ts-admin: app.ts

/* here i am more or less just kicking off the angular application after i import app.module.ts */
import { appModule } from './app.module';

appModule.run(["$rootScope", "$location", ...,
    function ($rootScope, $location, ...) {
  ..
}

appModule.controller('appController', ['$scope', ..,
    function ($scope: any, ...) {
  ..
}

ср c -ts-admin: app.module.ts

/** here (1) i am initializing all angular controllers, services, factories from the ADMIN package & (2) importing the COMMON module  */

import angular from 'angular';
import ngRoute from 'angular-route';
import uiRouter from 'angular-ui-router';
import 'angular-messages';
import 'angular-translate';
import dptCommonModuleName from '../src-ts-common/common.module';

var modulezz;
modulezz = [dptCommonModuleName, ngRoute, uiRouter, 'ui.multiselect', 'ui.bootstrap', 'ui.bootstrap-slider', 'ui.bootstrap.buttons', 'duScroll',
        'ngMessages', 'colorpicker.module', 'angular-bind-html-compile', 'pascalprecht.translate'];

export var appModule = angular.module("DPT", modulezz);
export var appModuleName = appModule.name;

/**
 * Services
 */
angular.module(appModuleName).service("systemParameterService", systemParameterService);
angular.module(appModuleName).service("statisticsService", statisticsService);
angular.module(appModuleName).service("deletionCheckService", deletionCheckService);
...

ср c -ts-admin: app.initializer.ts

/** here i have removed (1) the import of angular.module.ts and (2) the initialization of angular controller and service "initializerController" and "initializationService" */

import angular from "angular";
import { filterService } from "../src-ts-common/service/filter-service-model";

export class InitializerController {
    static $inject = ...etc...
    constructor(...etc...) {

    /* THIS IS KICKED OFF BY AN ANGULAR ROUTE, THIS KICKS OFF THE InitializerController BELOW */

    }
}

export class InitializerService {
    static $inject = ["$stateParams", "$window", "$timeout", "filterService", ...etc...];
    constructor(private $stateParams, private $window, private $timeout, private filterService: filterService, ...etc...) {

        /* THIS IS WHERE THE DEPENDENCY INJECTION FAILS */

    }
}

ср c -ts-common: common.module.ts

/* here i have added the initialization of the angular service filterService and all other services, factories, .. contained in that module */

var moduleName = angular.module("DPT.COMMON",[]).name
export default moduleName;

angular.module(moduleName).factory("filterModel", function () { return filterModel; });
angular.module(moduleName).factory("filterPresetModel", function () {return filterPresetModel;});
angular.module(moduleName).factory("productModel", function () {return productModel;});
angular.module(moduleName).factory("propertyProfileModel", [function () {return propertyProfileModel;}]);
angular.module(moduleName).factory("propertyValueModel",function () {return propertyValueModel;});

ср c - ts-common: filter.service.ts

/ ** здесь я (1) удалил импорт common.module и (2) инициализировал angular .module (..). service ( "filterService", ..) * /

import angular from "angular";

export class filterService {
    static $inject = [];
    constructor() {
    /* ...simplified... */
    }
}

1 Ответ

1 голос
/ 07 января 2020

Ваши зависимости инвертированы , Module должен импортировать свои файлы (другие модули или фильтры / услуги / компоненты).

Если вы будете следовать этому, ваш AppModule будет импортировать его дочерние модули, которые, в свою очередь, будут импортировать свои сервисы.

Это означает, что ваши сервисы должны только экспортировать класс. Соответствующий модуль должен импортировать класс обслуживания, зарегистрировать его в модуле и экспортировать имя модуля. Родительский модуль должен импортировать свои дочерние модули.

// serviceX.js

export class serviceX {
  static $inject=[];
  ...
}
// childModule.js

import {serviceX} from './services/serviceX.js';
import {componentY} from './components/componentY.js';
import angular from 'angular';

export default angular.module('childModule', [])
.service('serviceX', serviceX)
.component('componentY', componentY)
// ... rest of the childModule deps
.name;
// appModule.js

import {externalDep} from 'external-dep';
import childModule from './modules/childModule';
import angular from 'angular';

const appModule = anguler.module('appModule', [externalDep, childModule]).name;

angular.bootstrap(document, [appModule]);
...