我尝试将Rails与Angular集成,以便使用Angular将我的应用程序的一部分转换为单页应用。我有一个主模块,其中包含以下(coffeescript)代码用于路由:
MainApp.config ($routeProvider) ->
$routeProvider
.when '/',
{
templateUrl: 'post_archive.html'
}
.when '/new',
{
templateUrl: 'new_post.html'
}
.when '/:postSlug',
{
templateUrl: 'show_post.html'
}
.when '/:postSlug/edit',
{
templateUrl: 'edit_post.html'
}
.otherwise
redirectTo: '/'
该网站此部分的主视图以此haml
开头%div{ ng_controller: 'PostCtrl', ng_init: 'init()', ng_cloak: true }
PostCtrl有这个初始化函数:
$s.init = ->
$s.getPost().then ->
$s.getPostList() unless $s.postList
$s.getPreviousPost()
$s.getNextPost()
这个想法是,当前帖子以及下一个和上一个帖子需要重新计算,但是postList应该保持不变,因此不需要在每次页面加载时重新获取它。
然而,确实如此。似乎范围被转储到每个页面加载上,这意味着它根本不像单页应用程序那样表现,并且只要链接被跟踪,postList重新加载就会闪烁在应用程序内。
链接'呈现的HTML看起来像这样,例如:
<a id="link_name" ng_href="#/post-name" class="ng-binding" href="#/post-name">
Post Name
</a>
知道我在这里做错了什么吗? (这是否与角度似乎在最终的URL斜杠之前插入的所有磅符号有关?)
答案 0 :(得分:1)
这是预期的行为。如果在init上调用scope.init()
,则应在页面加载时调用 ,因为每次访问其控制器路由时,范围都将被绑定(并初始化)。
要避免这种行为,只需按需拨打init()
,或者 - 更好 - 将postList
升级到范围层次结构中的更高级别(ng-view
以上,路由更改需要将范围放置并重新绑定到视图),例如在$rootScope
。这样,它的初始化/评估将不会与$s
范围的init。
您可以在最顶层的范围内定义postList
, - 它将继承原型(即使是一个单词吗?):
$rootScope.postList = [];
将它保存在父控制器中也是足够的 - 只要它在层次结构中高于路由器的范围(ng-view
所在的位置),因为相同的规则适用于具有控制器范围的继承。这些方面的内容 [2] :
// in the view
%div { ng_contoller: 'ParentCtrl' }
%div { ng_view }
%div{ ng_controller: 'PostCtrl', ng_init: 'init()', ng_cloak: true }
// in ParentCtrl
$s.postList = [];
[1] 小心!未经测试!
[2] 伪造代码的风险 - 我真的不知道HAML!