在 Angular 2 中动态加载组件需要 Traceur?
Dynamically loading a component in Angular 2 requires Traceur?
我的代码应该根据客户名称和设置加载一个组件,两者都是从后端接收的字符串。
我尝试使用编译器编译模块然后获取组件工厂,但是在尝试编译时,angular 似乎需要 Traceur 我没有安装或引用。 Angular 2 个文档根本没有提到它。
模块的运行时编译是否必须使用 Traceur,还是我做错了什么?
Error loading http://localhost:8099/customers/zd/march/traceur
Unable to load transpiler to transpile http://localhost:8099/ng_app/app/customer-page/zd/zd.module.ts
Error loading http://localhost:8099/ng_app/app/customer-page/zd/zd.module.ts
- Traceur 显然不在 /customers/zd/march/traceur,但为什么需要它?
代码(仅动态加载部分,为简洁起见):
compiler.compileModuleAndAllComponentsAsync(module)
.
调用失败结果
let customer = self.service.getCustomerName();
let customer_view = feedbackChannel.customSettings.view;
console.log('loading module for customer ' + customer);
System.import('/ng_app/app/customer-page/' + customer + '/' + customer + '.module.ts')
.then((module) => {
console.log('compiling module for customer ' + customer);
return self.compiler.compileModuleAndAllComponentsAsync(module);
})
.then((moduleWithFactories) => {
console.log('loading class for customer view ' + customer_view);
self.componentFactory = moduleWithFactories.componentFactories.find((factory) => {
return (factory.componentType.name === customer_view);
});
console.log('Is customer view loaded? ' + (self.componentFactory != null));
// try loading the component here
let viewContainerRef = this.customerViewHost.viewContainerRef;
viewContainerRef.clear();
viewContainerRef.createComponent(this.componentFactory);
})
.catch((err) => {
console.log('Error when loading component: ' + err);
});
正在加载的模块:
import { NgModule } from '@angular/core';
import { ZDPageComponent } from './zd-page.component';
@NgModule({
declarations: [ ZDPageComponent],
exports: [ ZDPageComponent ]
})
export class ZDModule { }
package.json,以防我missing/misusing一些angular参考:
{
"dependencies": {
"@angular/animations": "^4.1.3",
"@angular/common": "^4.1.3",
"@angular/compiler": "^4.1.3",
"@angular/compiler-cli": "^4.1.3",
"@angular/core": "^4.1.3",
"@angular/forms": "^4.1.3",
"@angular/http": "^4.1.3",
"@angular/platform-browser": "^4.1.3",
"@angular/platform-browser-dynamic": "^4.1.3",
"@angular/platform-server": "^4.1.3",
"@angular/router": "^4.1.3",
"angular-in-memory-web-api": "^0.3.1",
"body-parser": "1.10.x",
"bootstrap": "^3.3.6",
"browserify": "^14.1.0",
"busboy": "^0.2.9",
"chart.js": "^2.5.0",
"compression": "^1.6.2",
"configstore": "^2.1.0",
"connect-loki": "^1.0.9",
"cookie-parser": "^1.4.3",
"core-js": "^2.4.1",
"email-addresses": "^2.0.2",
"express": "^4.10.3",
"express-session": "^1.15.1",
"express-xml-bodyparser": "^0.3.0",
"fs-extra": "^1.0.0",
"konfig": "^0.2.0",
"multer": "^1.3.0",
"node-sass-middleware": "^0.9.8",
"passport": "^0.3.2",
"passport-local": "^1.0.0",
"plivo": "^0.4.1",
"reflect-metadata": "^0.1.8",
"request": "^2.79.0",
"request-promise-native": "^1.0.3",
"rxjs": "5.0.0-rc.4",
"sendgrid": "^4.7.1",
"systemjs": "^0.19.41",
"typescript": "^2.3.2",
"uglify-js": "^2.7.5",
"useragent": "^2.1.11",
"winston": "^2.3.0",
"winston-loggly-bulk": "^1.3.4",
"xlsx": "^0.9.8",
"xml2js": "^0.4.17",
"zone.js": "^0.7.2"
},
"scripts": {
"postinstall": "node npm_scripts/postinstall.js",
"startDev": "concurrent \"tsc -w\" \"node tm_web.js\"",
"clean": "rm -rf dist",
"build": "npm run clean && tsc",
"browserify": "browserify -s main client/public/ng_app/dist/main.js > client/public/ng_app/dist/bundle.js",
"minify": "uglifyjs client/public/ng_app/dist/bundle.js --screw-ie8 --compress --mangle --output client/public/ng_app/dist/bundle.min.js",
"build_prod": "npm run build && npm run browserify && npm run minify",
"start": "node tm_web.js",
"migrate": "node ./server/model_migartion/migrate.js"
},
"devDependencies": {
"concurrently": "^3.4.0",
"rxjs-system-bundle": "^5.1.1-2"
}
}
system.js 加载程序,以防我在这里遗漏了一些东西:
(function(global) {
System.config({
paths: {
// paths serve as alias
'angular:': '/assets/javascript/angular/'
},
bundles: {
"angular:Rx.system.min.js": [
"rxjs",
"rxjs/*",
"rxjs/operator/*",
"rxjs/observable/*",
"rxjs/scheduler/*",
"rxjs/symbol/*",
"rxjs/add/operator/*",
"rxjs/add/observable/*",
"rxjs/util/*"
]
},
map: {
'app': 'app',
'@angular/core': 'angular:core.umd.js',
'@angular/common': 'angular:common.umd.js',
'@angular/compiler': 'angular:compiler.umd.js',
'@angular/platform-browser': 'angular:platform-browser.umd.js',
'@angular/platform-browser-dynamic': 'angular:platform-browser-dynamic.umd.js',
'@angular/http': 'angular:http.umd.js',
'@angular/router': 'angular:router.umd.js',
'@angular/forms': 'angular:forms.umd.js',
// other libraries
//'rxjs': 'angular:Rx.min.js',
'angular-in-memory-web-api': 'angular:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js',
},
// packages tells the System loader how to load when no filename and/or no extension
packages: {
app: {
defaultExtension: 'js',
meta: {
'./app/*.js': {
loader: './systemjs-angular-loader.js'
}
}
},
rxjs: {
//defaultExtension: 'js'
defaultExtension: false
}
}
});
})(this);
tsconfig,如果问题出在如何定义 typescript 编译器上:
{
"compileOnSave": true,
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"lib": ["es2015", "dom"],
"noImplicitAny": false,
"suppressImplicitAnyIndexErrors": true,
"outDir": "client/public/ng_app/dist"
},
"include": [
"client/public/ng_app/app",
"client/public/ng_app/main.ts"
]
}
我怀疑你应该导入转译后的 js
文件而不是原始文件 ts
另外我会编译NgModule
class
System.import(...)
.then((module: any) => module['ZDModule'])
.then((module) => self.compiler.compileModuleAndAllComponentsAsync(module))
.then(...
我的代码应该根据客户名称和设置加载一个组件,两者都是从后端接收的字符串。
我尝试使用编译器编译模块然后获取组件工厂,但是在尝试编译时,angular 似乎需要 Traceur 我没有安装或引用。 Angular 2 个文档根本没有提到它。
模块的运行时编译是否必须使用 Traceur,还是我做错了什么?
Error loading http://localhost:8099/customers/zd/march/traceur
Unable to load transpiler to transpile http://localhost:8099/ng_app/app/customer-page/zd/zd.module.ts
Error loading http://localhost:8099/ng_app/app/customer-page/zd/zd.module.ts
- Traceur 显然不在 /customers/zd/march/traceur,但为什么需要它?
代码(仅动态加载部分,为简洁起见):
compiler.compileModuleAndAllComponentsAsync(module)
.
let customer = self.service.getCustomerName();
let customer_view = feedbackChannel.customSettings.view;
console.log('loading module for customer ' + customer);
System.import('/ng_app/app/customer-page/' + customer + '/' + customer + '.module.ts')
.then((module) => {
console.log('compiling module for customer ' + customer);
return self.compiler.compileModuleAndAllComponentsAsync(module);
})
.then((moduleWithFactories) => {
console.log('loading class for customer view ' + customer_view);
self.componentFactory = moduleWithFactories.componentFactories.find((factory) => {
return (factory.componentType.name === customer_view);
});
console.log('Is customer view loaded? ' + (self.componentFactory != null));
// try loading the component here
let viewContainerRef = this.customerViewHost.viewContainerRef;
viewContainerRef.clear();
viewContainerRef.createComponent(this.componentFactory);
})
.catch((err) => {
console.log('Error when loading component: ' + err);
});
正在加载的模块:
import { NgModule } from '@angular/core';
import { ZDPageComponent } from './zd-page.component';
@NgModule({
declarations: [ ZDPageComponent],
exports: [ ZDPageComponent ]
})
export class ZDModule { }
package.json,以防我missing/misusing一些angular参考:
{
"dependencies": {
"@angular/animations": "^4.1.3",
"@angular/common": "^4.1.3",
"@angular/compiler": "^4.1.3",
"@angular/compiler-cli": "^4.1.3",
"@angular/core": "^4.1.3",
"@angular/forms": "^4.1.3",
"@angular/http": "^4.1.3",
"@angular/platform-browser": "^4.1.3",
"@angular/platform-browser-dynamic": "^4.1.3",
"@angular/platform-server": "^4.1.3",
"@angular/router": "^4.1.3",
"angular-in-memory-web-api": "^0.3.1",
"body-parser": "1.10.x",
"bootstrap": "^3.3.6",
"browserify": "^14.1.0",
"busboy": "^0.2.9",
"chart.js": "^2.5.0",
"compression": "^1.6.2",
"configstore": "^2.1.0",
"connect-loki": "^1.0.9",
"cookie-parser": "^1.4.3",
"core-js": "^2.4.1",
"email-addresses": "^2.0.2",
"express": "^4.10.3",
"express-session": "^1.15.1",
"express-xml-bodyparser": "^0.3.0",
"fs-extra": "^1.0.0",
"konfig": "^0.2.0",
"multer": "^1.3.0",
"node-sass-middleware": "^0.9.8",
"passport": "^0.3.2",
"passport-local": "^1.0.0",
"plivo": "^0.4.1",
"reflect-metadata": "^0.1.8",
"request": "^2.79.0",
"request-promise-native": "^1.0.3",
"rxjs": "5.0.0-rc.4",
"sendgrid": "^4.7.1",
"systemjs": "^0.19.41",
"typescript": "^2.3.2",
"uglify-js": "^2.7.5",
"useragent": "^2.1.11",
"winston": "^2.3.0",
"winston-loggly-bulk": "^1.3.4",
"xlsx": "^0.9.8",
"xml2js": "^0.4.17",
"zone.js": "^0.7.2"
},
"scripts": {
"postinstall": "node npm_scripts/postinstall.js",
"startDev": "concurrent \"tsc -w\" \"node tm_web.js\"",
"clean": "rm -rf dist",
"build": "npm run clean && tsc",
"browserify": "browserify -s main client/public/ng_app/dist/main.js > client/public/ng_app/dist/bundle.js",
"minify": "uglifyjs client/public/ng_app/dist/bundle.js --screw-ie8 --compress --mangle --output client/public/ng_app/dist/bundle.min.js",
"build_prod": "npm run build && npm run browserify && npm run minify",
"start": "node tm_web.js",
"migrate": "node ./server/model_migartion/migrate.js"
},
"devDependencies": {
"concurrently": "^3.4.0",
"rxjs-system-bundle": "^5.1.1-2"
}
}
system.js 加载程序,以防我在这里遗漏了一些东西:
(function(global) {
System.config({
paths: {
// paths serve as alias
'angular:': '/assets/javascript/angular/'
},
bundles: {
"angular:Rx.system.min.js": [
"rxjs",
"rxjs/*",
"rxjs/operator/*",
"rxjs/observable/*",
"rxjs/scheduler/*",
"rxjs/symbol/*",
"rxjs/add/operator/*",
"rxjs/add/observable/*",
"rxjs/util/*"
]
},
map: {
'app': 'app',
'@angular/core': 'angular:core.umd.js',
'@angular/common': 'angular:common.umd.js',
'@angular/compiler': 'angular:compiler.umd.js',
'@angular/platform-browser': 'angular:platform-browser.umd.js',
'@angular/platform-browser-dynamic': 'angular:platform-browser-dynamic.umd.js',
'@angular/http': 'angular:http.umd.js',
'@angular/router': 'angular:router.umd.js',
'@angular/forms': 'angular:forms.umd.js',
// other libraries
//'rxjs': 'angular:Rx.min.js',
'angular-in-memory-web-api': 'angular:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js',
},
// packages tells the System loader how to load when no filename and/or no extension
packages: {
app: {
defaultExtension: 'js',
meta: {
'./app/*.js': {
loader: './systemjs-angular-loader.js'
}
}
},
rxjs: {
//defaultExtension: 'js'
defaultExtension: false
}
}
});
})(this);
tsconfig,如果问题出在如何定义 typescript 编译器上:
{
"compileOnSave": true,
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"lib": ["es2015", "dom"],
"noImplicitAny": false,
"suppressImplicitAnyIndexErrors": true,
"outDir": "client/public/ng_app/dist"
},
"include": [
"client/public/ng_app/app",
"client/public/ng_app/main.ts"
]
}
我怀疑你应该导入转译后的 js
文件而不是原始文件 ts
另外我会编译NgModule
class
System.import(...)
.then((module: any) => module['ZDModule'])
.then((module) => self.compiler.compileModuleAndAllComponentsAsync(module))
.then(...