javascript - 如何将 Angular 2 应用程序集成到 Django 应用程序中

标签 javascript django angular

我一直在关注这个 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>

最佳答案

你应该注意几件事:

  1. Django 不是 Rails。它没有内置的方式来解析 TypeScript。您应该先编译所有 TypeScript 内容。
  2. 加载 Angular 应用只是普通的 HTML。您可以像往常一样使用您的模板。我不太确定如何在 Angular 2 中执行此操作,但由于它只是纯 HTML/JS,因此不会有任何区别:通过包含适当的文件,您将适本地引用 Angular。在我的许多项目中,我更喜欢(出于问题范围之外的原因)显式调用 angular.bootstrap。不知道 Angular 2 是否有相同的调用或不同的调用,但过程没有改变。
  3. Angular 2 模板不会被 django 处理,而是像静态文件一样处理。确保将它们放在应用程序的 static/ 目录中并适本地引用它们(例如,在你的主要 django 模板中,如果你声明你的 Angular 应用程序并且 stateProvider 仍然有效,你可以为状态声明一个模板 lke this: '{% static 'myapp/angular-templates/mytemplate.html' %}',前提是该文件夹存在)。
  4. 如果您有一个单独的 .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']);
     });
    
  5. 编辑(请注意这一点让人头疼)记住一定要引用{{ 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?
         })
     }])
    

所以记住:

  1. 请记住,AngularJS 与后端 fwk 是分离的,这对任何框架都适用——而不仅仅是 AngularJS 版本。
  2. 请记住,您需要以某种方式引用您需要在...静态文件中引用的静态文件 xD。传递变量的技巧将在任何框架中起作用:您只需在主模板中告诉 javascript 一个 django 变量的值(在引导您的框架之前),然后您的 js 框架将可以访问 javascript 中的值。
  3. 您永远不会从您的 fwk 访问 django 标签。
  4. Django 不会将任何东西转换成 JS。除非找到第 3 方 Assets 管道库,否则您需要准备好 .js 文件。

关于javascript - 如何将 Angular 2 应用程序集成到 Django 应用程序中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36316893/

相关文章:

javascript - 检查字符串中的字符是否唯一

php - 显示数据的最快方式

python - 检查 Django 用户是否设置了密码

javascript - 如果单击子angular2,如何停止父请求

javascript - 将新元素添加到 DOM Angular 时的动画

angular - 当我尝试安装 Angular 时权限被拒绝

javascript - angularjs - 有条件地显示/隐藏输入字段

javascript - TypeError: res.writeHead is not a function 第 6 章 Fullstack javascript development with MEAN

python - 无法解析余数 : '{{ list[loop.index0] }}'

python - 我可以使用复杂的键而不是字符串来访问 Django/Python 缓存解决方案