问题
I'm using Angular 1.6.7. I have created multiple modules in my app. How can I pass a constant (e.g. "rootURL") defined in a parent module (myApp) to a child module (childApp)? More specifically, I need to assign the value of "rootURL" to the templateUrl of childApp's component so we don't have to hard code the root directory for every module. I think I know how to share variables inside a controller, but don't know how to do that inside the definition of a component.
Here's a Plunker to demo. In app.module.js I defined a constant "config". What can I do so that when I define the component for "child" (components/child.component.js), instead of templateUrl: "components/child.html", I can say something like "config.rootURL + child.html"? We do not have to use constant.
Thank you in advance.
// 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", []);
})();
// components/child.component.js
(function(){
"use strict";
// Define controller
function childController() {
this.$onInit = function() {
var vm = this;
vm.child = {
"firstName": "Jack"
}
};
// end of $onInit()
}
// Define component
var child = {
templateUrl: "components/child.html"
, 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>
<!-- components/child.html -->
Child: {{vm.child.firstName}} {{vm.parent.lastName}}
回答1:
instead of templateUrl: "components/child.html", I can say something like "config.rootURL + child.html"?
Instead templateUrl
you can write template
with ng-include
:
template: '<ng-include src="getTemplateUrl()"/>',
and:
scope.getTemplateUrl = function () {
return config.rootURL + 'child.html';
};
Demo Plunker
Code example:
function childController(config) {
this.getTemplateUrl = function(){
return config.rootURL + 'child.html';
};
this.$onInit = function() {
var vm = this;
vm.child = {
"firstName": "Jack"
}
};
// end of $onInit()
}
// Define component
var child = {
//templateUrl: "components/child.html"
template: '<ng-include src="vm.getTemplateUrl()"/>'
, controller: childController
, controllerAs: "vm"
, bindings: {
parent: "<"
}
};
回答2:
When you register a constant using myApp.constant()
that value becomes inject-able just like any other service. You could inject it into a component's controller and use it, but by then angular has already downloaded (or tried to download) the template. You'd need to modify the URL at component registration time, however, inject-ables are not available yet when you're registering components.
I suggest you instead look into a feature called $http interceptors. You could write an interceptor to look for template requests and modify their url.
https://docs.angularjs.org/api/ng/service/$http
I'd suggest writing template urls with a token, then look for that token in an interceptor. For instance:
templateUrl: '{tplBase}/myTemplate.html'
Then an interceptor that looks for that token and swaps it for the root URL
myApp.config(function($httpProvider) {
//The interceptor factory is injectable, so inject your config constant here...
$httpProvider.interceptors.push(function(config) {
return {
'request': function(httpConfig) {
if (httpConfig.url.contains('{tplBase}')) {
httpConfig.url = httpConfig.url.replace('{tplBase}', config.rootUrl);
}
return httpConfig;
}
};
});
});
来源:https://stackoverflow.com/questions/46304412/angular-1-6-multiple-modules-sharing-global-variable-between-modules-compon