Angular 1.6 + Компоненты: передача констант между модулями

Как передать значение константы из одного модуля в другой? Заранее спасибо. Вот демонстрация Plunker. Константа «config» определена в app.module.js, и я хочу передать ее в child.module.js для определения константы «childConfig». Сейчас в консоли пишет "конфигурация не определена".

Заранее большое спасибо.

// app.module.js
(function(){
    "use strict";

    var myApp = angular
        .module("myApp", ["child"]);

    myApp.constant("config", {
        rootURL: "components/"
        , version: "myApp1.0.0"
    })
})();

// app.component.js
(function(){

    "use strict";

    // Define controller
    function mainController(){
        this.$onInit = function() {
            var mainVM = this;

            mainVM.parent = {
                "lastName": "Smith"
                , "firstName": "Jordan"
            };
        };

    }

    // Define component
    var mainComponent = {
        controller: mainController
        , controllerAs: "mainVM"
    };

    // Register controller and component
    angular.module("myApp")
        .controller("mainController", mainController)
        .component("mainComponent", mainComponent);

})();

//components/child.module.js
(function(){
    "use strict";

    var child = angular.module("child", []);
    
    child.constant("childConfig", config);

})();

//components/child.component.js
(function(){
    "use strict";

    // Define controller
    function childController(config) {
        this.$onInit = function() {
            var vm = this;
            
            vm.getTemplateUrl = function(){
              return config.rootURL + 'child.html';
            }
            vm.rootURL = config.rootURL;
            vm.version = config.version;
            vm.child = {
              "firstName": "Jack"
            }
        };
        // end of $onInit()
    }

    // Define component
    var child = {
        //templateUrl: vm.getTemplateUrl + "child.html"
        //templateUrl: "components/child.html"
        template: "<ng-include src='vm.getTemplateUrl()'/>"
        , controller: childController
        , controllerAs: "vm"
        , bindings: {
            parent: "<"
        }
    };


    // Register controller and component
    angular.module("child")
        .controller("childController", childController)
        .component("child", child);

})();
<!DOCTYPE html>
<html>

  <head>
    <script src="//code.angularjs.org/snapshot/angular.js"></script>
    <link rel="stylesheet" href="style.css">
    <script src="app.module.js"></script>
    <script src="app.component.js"></script>
    <script src="components/child.module.js"></script>
    <script src="components/child.component.js"></script>
  </head>

  <body ng-app="myApp" ng-controller="mainController as mainVM">
    Parent: {{mainVM.parent.firstName}} {{mainVM.parent.lastName}}<br>
    <child parent="mainVM.parent"></child>
  </body>

</html>


person Telly Ipock    schedule 19.09.2017    source источник
comment
Какой смысл определять одну и ту же константу дважды? Просто введите константу конфигурации везде, где вам это нужно.   -  person JB Nizet    schedule 19.09.2017
comment
Нет, я не определяю одну и ту же константу дважды. Фактическое приложение, над которым я работаю, намного больше и имеет много уровней. Мне нужно использовать родительскую константу в определении каждой дочерней константы, чтобы их можно было использовать в своих собственных контроллерах. И когда я обновлю rootURL, все дочерние URL-адреса будут изменены. Я обновил Plunker, чтобы продемонстрировать это.   -  person Telly Ipock    schedule 19.09.2017
comment
Не определяйте константу для ваших дочерних конфигураций. Определите службу, в которую вы можете внедрить корневую константу и вернуть объект, содержащий поля, значения которых зависят от введенной константы.   -  person JB Nizet    schedule 19.09.2017
comment
Это имеет смысл. Спасибо.   -  person Telly Ipock    schedule 20.09.2017


Ответы (1)


Я думаю, вы могли неправильно понять возможности фабрики constant. Он не должен быть изменяемым ни для одной из переменных, поэтому он не сможет использовать другого внешнего поставщика для составления своего значения, он будет обслуживать только чистое чистое значение.

С другой стороны, если вы не возражаете, для достижения желаемого результата можно использовать фабрику. По сути, вы можете создать фабрику, которая изготовит для вас строку на основе внедренного поставщика config.

Например:

child.factory("childConfigURL", ['config', function(config) {
    return config.rootURL + "/component/";
}]);

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

Примечание о константах:

constant(name, value);

Зарегистрируйте постоянный сервис с помощью $injector, например, строку, число, массив, объект или функцию. Как и значение, невозможно внедрить другие сервисы в константу.

Но, в отличие от значения, константу можно внедрить в функцию конфигурации модуля (см. angular.Module), и ее нельзя переопределить декоратором AngularJS.

Ссылка: $provide.constant

person lenilsondc    schedule 19.09.2017
comment
Спасибо. Это ответило на мой вопрос. - person Telly Ipock; 20.09.2017