![](/img/trans.png)
[英]Heroku - Symfony2 - Angular - app with angular errors - .js not loading?
[英]Angular JS and Symfony2
我目前正在使用Symfony2进行一个项目,并就此寻求一些建议。
我正在考虑以两种不同的方式使用混合应用程序a)登录页面应使用带CRF令牌的传统形式,并让symfonty2处理它。 b)所有内页(可能是模块)我希望它们是非AJAX,但其中的其他活动应该像单页一样。
例如,我有一个员工模块 。 当用户点击它完全从服务器(所有模板和表单等)加载时,现在员工模块下的每个活动(如添加/更新删除/视图等)都将通过AJAX加载,并且响应将以JSON(即AngularJS)返回。
我目前正在考虑使用FOSUserBundle在初始请求时返回html然后根据请求类型接受:application / json它将返回JSON(还记得add / updat delete / view部分吗?)。
我的问题是使用Angular Partials(html)文件或Symfony2 Twig更好吗? 或者使用Angular JS会更好,但是让那些部分由Symfony2 twig渲染? (我在想这里的Forms,想要从客户端和服务器端验证)
有没有人经历过类似的问题,如果是,那么使用AngularJS和Symfony2或任何其他框架开发HYBRID应用程序的方法是什么? 任何相关的想法表示赞赏。
我和你的情况一样。 AngularJS + Symfony2项目,REST API,使用FOSUserBundle登录等。
......各方面都有利有弊,所以没有正确的方法,我只想说出我的所作所为。
我选择AngularJS本机模板,没有CSRF验证,使用Twig构建的基本模板,服务器端验证,使用FOSJSRoutingBundle以及一些帮助程序(BuiltResponse和BaseController)。
通过逐字使用,我们解决了变量问题,但是我们的模板中会有更复杂的逻辑。
我们的应用程序也将具有不太可扩展性。 我们所有的表单模板都在Symfony应用程序中执行请求,AngularJS的最佳专业人员之一是从存储服务(如S3)或CDN(如Cloudfront)加载我们的控制器,模板等。 由于没有服务器端处理,我们的模板加载速度会快得多。 即使有缓存,Twig显然也比较慢。
根据我自己的经验,Twig和AngularJS模板都非常复杂。 我开始将它们组合在一起,但管理起来很痛苦。
我在前端创建了静态模板,使用相同的字段名称,这不是很好。 我们需要在每次手动更新表单时更新模板。 但这是我发现的最佳方式。 由于字段名称相同,我们在调整Angular控制器中的模型名称时不会遇到任何问题。
如果您要将软件创建为服务,则无论如何都需要执行此操作。 你不会在移动应用程序中加载应用程序中的表单模板吗?
显然,我们不在REST API中使用CSRF验证。 但是,如果您想这样做,则需要在每次加载表单时发出请求以获取CSRF令牌。 这真的非常糟糕。 因此,我们创建了一个CRUD,我们还需要创建一个“csrf-CRUD”,更多4条路由。 这没有任何意义。
我在表单中禁用了CSRF。
是的。 基本模板只是在我们的应用程序中加载任何路由。 这是我正在做的事情:
如果您使用的是html5 angularjs网址,这将有助于我们避免在用户直接访问某些应用程序URL时出错。 很简单。
如果我们在Angular中进行验证,我们需要在服务器端执行相同的操作,因此我们需要维护2个验证代码。 那很痛苦。 我们在表单中进行的每一项更改,都需要更改前面的验证,后面的验证以及Angular静态表单。 真的,真的很痛苦。
我基本上使用Symfony约束进行了服务器端验证。 对于每个请求,应用程序验证表单并检查是否发现任何错误,如果是,则获取第一个并将其作为响应发送。
在AngularJS中,应用程序检查错误键内是否有任何错误。 因此,我们在所有应用程序中都使用了一个进程来执行任何表单请求。 就像那样:
还有另一个问题:路线。 直接放url是不可靠的方法。 如果我们更改了网址中的任何内容,那么该路由就会消失,用户也不会喜欢。
为了解决这个问题,我们可以使用FOSJsRoutingBundle 。 使用该库,我们可以将路径名称直接放在Angular控制器中,它将填充路径的确切URL。 它与Symfony完全集成,因此参数可以很好地工作。
而是直接使用url,我们可以这样做:
Routing.generate('panel_products_show', {id: $routeParams.product_id});
瞧! 我们得到路线网址。
这将解决您遇到的最大问题。 但还有更多。
Symfony中的表单通常有一个前缀,如“publish_product”,因此每个字段都有一个名称,如[publish_product]name
。 啊,这对我来说是怎么回事。
在Angular中,publish_product不被视为数组。 您需要使用单引号来执行此操作,例如['publish_product']name
。 这真的很糟糕,我们需要更改每个键才能使用这种格式。 在AngularJS中,我这样做:
{{ formData('[publish_product]name') }}
绝对愚蠢。
最好的解决方案是简单地删除Symfony中的表单前缀,使用createNamedBuilder
方法而不是createBuilder
。 我让第一个参数为null,是的,我们不再需要使用前缀了。 现在,我们使用:
{{ formData.name }}
好多了。
每个请求都可以返回任何内容,我需要重复很多代码。 这真的很难维护,所以我只创建一些应用程序规则,构建响应,BaseController等。
createNamedBuilder
是一个createNamedBuilder
的方法。 对于我们拥有的每种形式,我们都需要这样做:
解决起来很简单。 我刚刚创建了一个BaseController,我正在扩展它的每个控制器。 我创建了一个简单的方法来完成它。
对于每条路线,我们不需要重复3条线,更好。
当我的应用程序开始增长时,我遇到了一个严重的问题:我的所有回答都不同。 这真的很难维持。 对于我正在做的每个请求,有时我使用“响应”,有时“数据”,错误消息在响应中丢失等。
所以,我决定创建一个buildResponse,我只需要设置一些参数,每个路由都得到相同的结果,甚至是GET路由。
response
键显示状态和消息。 它可能是错误或成功,并且消息是可选字段,可以是空白的。 例如,成功状态,显示消息“您创建了产品”。
data
键显示我需要的任何信息。 例如,用户添加了产品,现在他需要链接才能看到它。 在数据中,我把帖子的url,我很容易从AngularJS控制器获取它。
notifications
是我的业务逻辑的特定键。 每个操作都可以向用户返回通知。
你有什么钥匙并不重要。 最重要的是有一个标准化的响应,因为当你的应用程序增长时,它将非常有用。
这是我的控制器的路线:
完全标准化。 Scrutinizer代码质量工具说我的所有路由都是重复的。 :d
有一个BaseController和一个builtResponse会帮助你这么多。 当我开始重构我的代码时,每条路线丢失了大约4-10行。
详细信息: getFormError
返回表单的第一个错误。 这是我的方法:
public function getFormError(FormInterface $form)
{
if ($form->getErrors()->current()) {
return $form->getErrors()->current()->getMessage();
}
return 'errors.unknown';
}
...而buildResponse的参数是:1。状态。 我从BaseController中的常量中得到它。 它可以改变,所以我认为重要的是不要在每条路线中使用字符串值。 2.翻译信息。 (我使用preg_match来检查它是否有翻译格式,因为getFormError已经转换了错误)。 3.数据(数组)参数。 4.通知(数组)参数。
到目前为止,该项目只有一种受支持的语言。 当我开始使用多语言版本时,我将遇到另一个大问题:维护两个版本的翻译:后端消息和验证以及前端的文本。 这可能是个大问题。 当我得到最好的方法时,我会更新这个答案。
我花了几个月才得到这种方法。 如此多的代码重构和未来可能会更多。 所以我希望它可以帮助别人不需要这样做。
如果我有更好的方法来做到这一点,我会更新这个答案。
我不擅长写英文,所以这个答案可能会有许多语法错误。 对不起,我正在修理我所看到的内容。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.