我一直在关注这个 Tour of Heroes教程。我有一个 Django 应用程序,其结构可以简化如下
apps/my_app/migrations/
apps/my_app/__init__.py
apps/my_app/urls.py
apps/my_app/views.py
frontend_stuff/js/ javascripts here
frontend_stuff/css/ css here
英雄应用具有以下结构:
heroes/app/ contains all the .ts and .html files
heroes/node_modules/ angular2 and other libraries
heroes/styles.css css file
heroes/index.html
heroes/package.json and other config files
目前我已经使用 Django View 构建了一个 API,它通过 URL 处理 Http 请求并返回 JSON。但是我应该在哪里/如何将这个 Angular 应用程序放入当前的 Django 应用程序,以及如何在对 Django 后端发出初始 GET 请求时将 Angular 应用程序加载到浏览器中?
编辑:关于加载 HTML 和 JS 的更具体的问题:
由于 Angular 2 使用 Component
并且模板是由 Angular 而不是 Django 渲染的,如何让 Angular “访问”那些 html? @Luis 提到那些文件应该放在静态文件夹中,但是 {% static %}
是 Django 语法,它对 Angular 没有意义。
同样,我想 app/main
(如下所示)也应该放在 static 文件夹中。但是如何引用 Angular 内部的位置呢?谢谢!
System.import('app/main')
.then(null, console.error.bind(console));
更新:
我关注了this answer并使用了 /static/js/my_app/main
并且现在“大部分”加载正常。到目前为止,我所有的 js 文件似乎都已加载;但控制台日志显示某些 Angular 文件在成功加载之前会出现 404 错误。错误如下图:
system.src.js:1085 GET http://localhost:8000/static/js/node_modules/angular2/src/platform/browser.js 404 (NOT FOUND)fetchTextFromURL @ system.src.js:1085(anonymous function) @ system.src.js:1646ZoneAwarePromise @ angular2-polyfills.js:589(anonymous function) @ system.src.js:1645(anonymous function) @ system.src.js:2667(anonymous function) @ system.src.js:3239(anonymous function) @ system.src.js:3506(anonymous function) @ system.src.js:3888(anonymous function) @ system.src.js:4347(anonymous function) @ system.src.js:4599(anonymous function) @ system.src.js:337ZoneDelegate.invoke @ angular2-polyfills.js:332Zone.run @ angular2-polyfills.js:227(anonymous function) @ angular2-polyfills.js:576ZoneDelegate.invokeTask @ angular2-polyfills.js:365Zone.runTask @ angular2-polyfills.js:263drainMicroTaskQueue @ angular2-polyfills.js:482ZoneTask.invoke @ angular2-polyfills.js:434
system.src.js:1085 XHR finished loading: GET "http://localhost:8000/static/js/rbac/app/rbac.service.js".fetchTextFromURL @ system.src.js:1085(anonymous function) @ system.src.js:1646ZoneAwarePromise @ angular2-polyfills.js:589(anonymous function) @ system.src.js:1645(anonymous function) @ system.src.js:2667(anonymous function) @ system.src.js:3239(anonymous function) @ system.src.js:3506(anonymous function) @ system.src.js:3888(anonymous function) @ system.src.js:4347(anonymous function) @ system.src.js:4599(anonymous function) @ system.src.js:337ZoneDelegate.invoke @ angular2-polyfills.js:332Zone.run @ angular2-polyfills.js:227(anonymous function) @ angular2-polyfills.js:576ZoneDelegate.invokeTask @ angular2-polyfills.js:365Zone.runTask @ angular2-polyfills.js:263drainMicroTaskQueue @ angular2-polyfills.js:482ZoneTask.invoke @ angular2-polyfills.js:434
system.src.js:1085 XHR finished loading: GET "http://localhost:8000/static/js/node_modules/angular2/src/platform/browser.js".fetchTextFromURL @ system.src.js:1085(anonymous function) @ system.src.js:1646ZoneAwarePromise @ angular2-polyfills.js:589(anonymous function) @ system.src.js:1645(anonymous function) @ system.src.js:2667(anonymous function) @ system.src.js:3239(anonymous function) @ system.src.js:3506(anonymous function) @ system.src.js:3888(anonymous function) @ system.src.js:4347(anonymous function) @ system.src.js:4599(anonymous function) @ system.src.js:337ZoneDelegate.invoke @ angular2-polyfills.js:332Zone.run @ angular2-polyfills.js:227(anonymous function) @ angular2-polyfills.js:576ZoneDelegate.invokeTask @ angular2-polyfills.js:365Zone.runTask @ angular2-polyfills.js:263drainMicroTaskQueue @ angular2-polyfills.js:482ZoneTask.invoke @ angular2-polyfills.js:434
angular2-polyfills.js:332 Error: Error: XHR error (404 NOT FOUND) loading http://localhost:8000/static/js/node_modules/angular2/src/platform/browser.js(…)ZoneDelegate.invoke @ angular2-polyfills.js:332Zone.run @ angular2-polyfills.js:227(anonymous function) @ angular2-polyfills.js:576ZoneDelegate.invokeTask @ angular2-polyfills.js:365Zone.runTask @ angular2-polyfills.js:263drainMicroTaskQueue @ angular2-polyfills.js:482ZoneTask.invoke @ angular2-polyfills.js:434
system.src.js:1085 GET http://localhost:8000/static/js/node_modules/angular2/src/http.js 404 (NOT FOUND)
更新:以上错误是由于系统配置中的路径不正确造成的。现在一切都加载了以下配置:
<script>
System.config({
defaultJSExtensions: true,
map:{
angular2: '/static/js/node_modules/angular2',
rxjs: '/static/js/node_modules/rxjs'
},
packages: {
app: {
format: 'register',
defaultExtension: 'js'
}
}
});
System.import('/static/apps/my_app/app/main')
.then(null, console.error.bind(console));
</script>
最佳答案
你应该注意几件事:
- Django 不是 Rails。它没有内置的方式来解析 TypeScript。您应该先编译所有 TypeScript 内容。
- 加载 Angular 应用只是普通的 HTML。您可以像往常一样使用您的模板。我不太确定如何在 Angular 2 中执行此操作,但由于它只是纯 HTML/JS,因此不会有任何区别:通过包含适当的文件,您将适本地引用 Angular。在我的许多项目中,我更喜欢(出于问题范围之外的原因)显式调用
angular.bootstrap
。不知道 Angular 2 是否有相同的调用或不同的调用,但过程没有改变。 - Angular 2 模板不会被 django 处理,而是像静态文件一样处理。确保将它们放在应用程序的
static/
目录中并适本地引用它们(例如,在你的主要 django 模板中,如果你声明你的 Angular 应用程序并且 stateProvider 仍然有效,你可以为状态声明一个模板 lke this: '{% static 'myapp/angular-templates/mytemplate.html' %}',前提是该文件夹存在)。 如果您有一个单独的 .js 文件(是的,编译您的 .ts 文件,因为 Django 不会)用于您的主要 Angular 模块,请确保您可以以某种方式将 Django 的 STATIC_URL 内容提供给代码配置模块,以便找到模板(并直接使用 window.STATIC_URL 而不是静态 django 标记)。在 Angularjs 1 中,我这样做是为了初始化所有内容:
angular.element.ready(function() { window.STATIC_URL = '{{ STATIC_URL }}'; // more constants I'd need angular.bootstrap(['myAngularModule']); });
编辑(请注意这一点让人头疼)记住一定要引用
{{ something }}
或者{% something %
在 django 提供的模板中。然后像我在第 4 点中所做的那样分配给一个 JS 变量,这样值就可用了。就我而言,我不使用静态标记,而是使用 STATIC_URL 变量。{% static %}
,如您所说,不会在 Angular 模板内工作,因此不要使用它,只需将所需资源连接到 STATIC_URL(这与第 4 点中的代码相关)变量。这是 AngularJS 1 中 .js 文件中的示例。通过适当调整它,您应该在 AngularJS 2 文件中执行类似的操作:mymodule.config(['$stateProvider', function($stateProvider) { $stateProvider.state({ name: 'main', templateUrl: window.STATIC_URL + 'path/to/template.html' // perhaps better inject $window if you want to run test suites? }) }])
所以记住:
- 请记住,AngularJS 与后端 fwk 是分离的,这对任何框架都适用——而不仅仅是 AngularJS 版本。
- 请记住,您需要以某种方式引用您需要在...静态文件中引用的静态文件 xD。传递变量的技巧将在任何框架中起作用:您只需在主模板中告诉 javascript 一个 django 变量的值(在引导您的框架之前),然后您的 js 框架将可以访问 javascript 中的值。
- 您永远不会从您的 fwk 访问 django 标签。
- Django 不会将任何东西转换成 JS。除非找到第 3 方 Assets 管道库,否则您需要准备好 .js 文件。
关于javascript - 如何将 Angular 2 应用程序集成到 Django 应用程序中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36316893/