我正在Symfony2 Bundle中开发一个AngularJS 1.4应用程序。Symfony提供了"后端"(API)和Angular的前端(当然)。
我正在使用新的路由器,并坚持使用几个指南和最佳实践示例建议的组件驱动文件夹方法。但是,由于我使用gulp构建JavaScript,并且只包含完整的构建文件,因此Angular控制器无法找到它们的模板。
我给你看我不喜欢的解决方案:
(function () {
'use strict';
angular
.module('myModule', ['ngNewRouter', 'myModule.dashboard'])
.config(TemplateMapping)
.controller('AppController', AppController);
/* @ngInject */
function AppController ($router) {
$router.config([
{ path: '/', redirectTo: '/dashboard' },
{ path: '/dashboard', component: 'dashboard' }
]);
}
/* @ngInject */
function TemplateMapping($componentLoaderProvider) {
$componentLoaderProvider.setTemplateMapping(function (name) {
return {
'dashboard': '/bundles/mybundle/templates/dashboard/dashboard.html'
}[name];
});
}
}());
我在src/myBundle/Resources/js/
中编写我的Angular代码,而gulp将最终构建放在src/myBundle/Resources/public/
中,然后在包含Angular应用程序的Twig模板中可用。
我现在正在做的,基本上是把我的组件的模板不是他们所属的地方(这将是src/myBundle/Resources/js/components/dashboard/
的仪表板的例子),但进入src/myBundle/Resources/public/templates
。
我必须通过$componentLoaderProvider.setTemplateMapping()
告诉路由器模板位于其他地方。
我有两个问题:
- 我可以用一种更优雅的方式解决这个模板位置问题吗?
- 我可以直接告诉路由器(在
AppController
)模板在哪里吗?
基于API的架构最酷的事情是你可以将后端应用(API)与前端应用(AngularJS应用)解耦。
我建议为前端和后端创建两个独立的应用程序。每个应用程序都应该在自己的Git存储库中,最终可以托管在自己的服务器上:- Symfony应用程序遵循Symfony最佳实践,只公开一个REST API。它包含所有的业务逻辑。它没有模板(你可以删除Twig)。数据最好以JSON形式公开。 AngularJS应用程序依赖于所有你想要的前端工具(Gulp, Yeoman…)并消耗API。它管理演示文稿,只包含"资产"(静态
index.html
文件,JavaScript文件,CSS样式表,图像…)。API是双方之间的契约,它们可以单独发展。维护方便,耦合紧密。前端应用程序甚至可以直接托管在CDN上,如Amazon CloudFront或GitHub页面,以获得最佳性能。
我已经写了一篇文章详细介绍了这种方法,并展示了我构建的一些工具。它使用Symfony和AngularJS。
如果你仍然希望有一个单一的应用程序:
- 把AngularJS应用放到一个非公开的目录中,比如
app/frontend
- 配置Gulp脚本,将dist文件写入
web/
- 小心CSRF攻击(看看我的DunglasAngularCsrfBundle)
最好的方法是将前端和后端分开,即使将后端更改为另一种技术,也不需要更改前端。
还有两个git项目可以帮助你有一个更好的应用程序。
1) FOSJsRoutingBundle
https://github.com/FriendsOfSymfony/FOSJsRoutingBundle它允许你在JavaScript代码中使用Symfony路由
2) angular-schema-form
https://github.com/json-schema-form/angular-schema-form这是一个动态表单生成器。它根据JSON模式创建并验证表单。
所以我在Symfony中创建了一个Angular模式表单序列化器,将一个Symfony表单转换为一个Jason模式,Angular - Schema - Form可以使用它来动态生成我的表单。在这种情况下,我不需要在html中实现表单。即使我更改了API,我也只需要为表单提供相同的Jason模式。
最好的方法是将你的Angular应用与Symfony后端完全分离。但是,如果你想在你的旧应用的一小部分使用Angular,你可以把你的baseURL传递给你的组件,例如:
<yourComponent baseurl="{{ app.request.scheme ~ '://' ~
app.request.httpHost ~ app.request.basePath }}"></yourComponent>
,然后在templateUrl函数
中使用 templateUrl: function($attrs) {
return $attrs.baseurl + 'templats/yourComponent.template.html';
}