简体   繁体   English

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

[英]How to integrate an Angular 2 app into a Django app

I've been following this Tour of Heroes tutorial. 我一直在关注这个英雄之旅教程。 I have a Django app whose structure can be simplified as follows 我有一个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

the hero app has the following structure: 英雄应用程序具有以下结构:

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

currently i've built an API using Django View that handles Http Request via URL and returns JSON. 目前我已经使用Django View构建了一个API,它通过URL处理Http请求并返回JSON。 But where/how should I place this Angular app into the current Django app, and how can I load the Angular app into the browser upon the initial GET request to Django backend? 但是我应该在哪里/如何将这个Angular应用程序放入当前的Django应用程序中,以及如何在向Django后端发出初始GET请求时将Angular应用程序加载到浏览器中?

EDIT: more specific questions on loading HTML and JS: 编辑:关于加载HTML和JS的更具体的问题:

Since Angular 2 uses Component and the templates are rendered by Angular rather than Django, how to let Angular "access" those html? 由于Angular 2使用Component而模板是由Angular而不是Django呈现的,如何让Angular“访问”那些html? @Luis mentioned that those files should be placed inside the static folder, but {% static %} is Django syntax which wouldn't make sense to Angular. @Luis提到这些文件应放在静态文件夹中,但{% static %}是Django语法,这对Angular没有意义。

Similarly, I suppose app/main (shown below) should also be placed in static folder. 同样,我认为app/main (如下所示)也应放在静态文件夹中。 But how to refer to the location inside Angular? 但是如何引用Angular内部的位置? Thanks! 谢谢!

  System.import('app/main')
        .then(null, console.error.bind(console));

UPDATE: i followed this answer and used /static/js/my_app/main and it's "mostly" loading fine now. 更新:我按照这个答案,并使用/static/js/my_app/main ,它现在“大部分”加载正常。 so far all my js files seem to be loaded; 到目前为止,我的所有js文件似乎都被加载了; but the console log shows that some angular files give 404 error before loading successfully. 但控制台日志显示某些角度文件在加载成功之前会出现404错误。 error as shown below: 错误如下图所示:

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)

Update: the above error was due to incorrect path in System Confing. 更新:上述错误是由于系统配置中的路径不正确造成的。 Now everything loads with the following config: 现在一切都加载以下配置:

<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>

You should take care of few things: 你应该照顾好几件事:

  1. Django is not Rails. Django不是Rails。 It does not come with a built-in way to parse TypeScript. 它没有内置的解析TypeScript的方法。 You should compile all your TypeScript stuff first. 您应该首先编译所有TypeScript内容。
  2. Loading Angular app is just regular HTML. 加载Angular应用程序只是常规HTML。 You can use your templating as always. 您可以像往常一样使用模板。 I'm not pretty sure how to do it in Angular 2, but since it is just plain HTML/JS, it will make no difference: by including the appropriate files, you will reference Angular appropriately. 我不太确定如何在Angular 2中做到这一点,但由于它只是简单的HTML / JS,它没有区别:通过包含适当的文件,你将适当地引用Angular。 In many of my projects, I prefer (for reasons out of the question's scope) to call angular.bootstrap explicitly. 在我的许多项目中,我更喜欢(出于问题范围的原因)明确调用angular.bootstrap Don't know if Angular 2 has the same call or a different one, but the process does not change. 不知道Angular 2是否具有相同的呼叫或不同的呼叫,但该过程不会改变。
  3. Angular 2 templates will not be processed by django but instead treated like static files. django不会处理Angular 2模板,而是像静态文件一样处理。 Ensure you put them in your app's static/ directory and reference them appropriately (eg in your main django template, if you declare your angular app and stateProvider is still valid, you could declare a template for the state lke this: '{% static 'myapp/angular-templates/mytemplate.html' %}', provided that folder exists). 确保将它们放在应用程序的static/目录中并适当地引用它们(例如,在你的主django模板中,如果你声明你的角度应用程序和stateProvider仍然有效,你可以为状态声明一个模板lke this:'{%static' myapp / angular-templates / mytemplate.html'%}',前提是该文件夹存在)。
  4. In the case that you have a separate .js file (yes, COMPILE your .ts files since Django will not) for your main angular module, ensure somehow you can provide the STATIC_URL content from django to the code which configures the modules, for templates to be found (and use window.STATIC_URL directly instead of the static django tag). 如果您的主角度模块有一个单独的.js文件(是的,COMILE你的.ts文件,因为Django不会),请确保以某种方式提供从django到配置模块的代码的STATIC_URL内容,用于模板找到(并直接使用window.STATIC_URL而不是静态django标记)。 In Angularjs 1, I do this to initialize everything: 在Angularjs 1中,我这样做是为了初始化所有内容:

      angular.element.ready(function() { window.STATIC_URL = '{{ STATIC_URL }}'; // more constants I'd need angular.bootstrap(['myAngularModule']); }); 
  5. Edit (please pay attention to this point which causes headaches) Remember that you must reference {{ something }} or {% something %} in the django served template. 编辑 (请注意导致头痛的这一点)请记住,您必须在django服务模板中引用{{ something }}{% something %} Then you assign to a JS variable as I did in point 4, so the values are available. 然后你像我在第4点那样分配一个JS变量,所以这些值是可用的。 In my case, I don't use static tag, but STATIC_URL variable. 就我而言,我不使用静态标记,而是使用STATIC_URL变量。 {% static %} , as you said, will not work inside angular templates, so instead of using it, just concatenate the required resource to the STATIC_URL (this is correlative with code in point 4) variable. 正如你所说, {% static %}在角度模板中不起作用,所以不要使用它,只需将所需资源连接到STATIC_URL(这与第4点中的代码相关)变量。 This is an example inside a .js file in AngularJS 1. By tweaking it appropriately, you should do something similar in your AngularJS 2 files: 这是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? }) }]) 

So remember: 所以请记住:

  1. Remember that AngularJS, and this will hold true for any framework - not just AngularJS versions-, is decoupled of the backend fwk. 请记住AngularJS,这对于任何框架都是正确的 - 不仅仅是AngularJS版本 - 与后端fwk分离。
  2. Remember that you need to reference, somehow, where are the static files you need to reference in your... static files xD. 请记住,您需要以某种方式引用您需要在静态文件xD中引用的静态文件。 The trick of passing the variable will do the work in any framework: you simply tell javascript the value of a django variable in the main template (before bootstrapping your framework), and then your js framework will have access to the value in javascript. 传递变量的技巧将在任何框架中完成:你只需告诉javascript主模板中django变量的值(在引导你的框架之前),然后你的js框架就可以访问javascript中的值了。
  3. You will never access django tags from your fwk. 你永远不会从你的fwk访问django标签。
  4. Django does not convert anything to JS. Django没有将任何东西转换为JS。 You need your .js files ready unless you find a 3rd party assets pipeline library. 除非找到第三方资产管道库,否则您需要准备好.js文件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM