[英]Rotating View in Ember.js
I'm trying to make a little Ember View widget that rotates the template every 3 seconds. 我正在尝试制作一个小的Ember View小部件,该小部件每3秒旋转一次模板。 This is far as I have gotten, but it doesn't seem to be working correctly. 到目前为止,这还算是正常的。 Am I going with the right approach or can anyone suggest how to do this? 我要采用正确的方法还是有人可以提出建议?
UPDATED: 更新:
This almost works, but it doesn't cycle through the templates correctly as it is updating far too frequently. 这几乎可行,但是由于更新太频繁,因此无法正确循环浏览模板。 Here's a jsfiddle . 这是一个jsfiddle 。 (WARNING, Fiddle becomes unresponsive eventually because it gets overloaded with updates to the DOM) (警告,Fiddle最终变得无响应,因为它过载了DOM更新)
App.RotatingView = Ember.View.extend
templateString: null
views: ["a", "b", "c"]
init: ->
@set 'templateString', @_getNextTemplate()
@_super()
template: (->
Ember.Handlebars.compile(@get 'templateString')
).property('templateString')
templateDidChange: (->
setInterval =>
@set 'templateString', @_getNextTemplate()
Ember.run.next => @rerender()
, 3000
).observes("templateString")
_getNextTemplate: ->
views = @get('views')
length = views.length
currentTemplateIndex = views.indexOf this.get('templateString')
if (currentTemplateIndex + 1) == length
return views[0]
else
return views[currentTemplateIndex + 1]
UPDATE #2 更新#2
I also attempted the ContainerView
approach suggested by @Unspecified below, but I get 'Cannot call methods 'childViewsDidChange' of undefined. 我也尝试了下面@Unspecified建议的ContainerView
方法,但是得到了“无法调用未定义的方法'childViewsDidChange”。
App.RotatingView = Ember.ContainerView.extend
views: Em.A(["a", "b", "c"])
childViews: (->
views = @get('views')
return views.map (view) -> Ember.View.create({template: Ember.Handlebars.compile(view)})
).property('views.@each')
init: ->
@set 'currentView', @get('childViews.firstObject')
@_super()
viewDidChange: (->
setInterval =>
@set 'currentView', @_getNextView()
, 3000
).observes('currentView')
_getNextView: ->
views = @get('childViews')
length = views.length
currentTemplateIndex = views.indexOf this.get('templateString')
if (currentTemplateIndex + 1) == length
return views[0]
else
return views[currentTemplateIndex + 1]
There's a problem with your templateDidChange method: since it observes('templateString')
, it will be run every time that templateString changes, and so you'll end up with an awful lot of setInterval calls (I think that's the reason your latest fiddle bogs down). templateDidChange方法存在问题:由于它会observes('templateString')
,因此每次templateString更改时都将运行它,因此最终会有很多setInterval调用(我认为这就是您最近的小提琴的原因)沼泽)。
Here 'sa fiddle that seems to work as you expect - I simply moved the setInterval into the init
method. 这似乎像您期望的那样起作用-我只是将setInterval移到了init
方法中。
Problem 问题
The problem with your approach is that you made template
computed property with no dependencies, so it gets calculated only once when it was called at the beginning, it wont get recalculated because it is not dependent on any thing 您的方法的问题在于,您使template
计算属性没有依赖性,因此在开始调用时仅对其进行一次计算,因此不会重新计算,因为它不依赖于任何事物
There are a lot of ways to accomplish this(Skipping the rotations
& _randomTemplate
from the answer) 有很多方法可以做到这一点(从答案中跳过rotations
和_randomTemplate
)
1. 1。
App.RotatingView = Ember.View.extend
template: (->
Ember.Handlebars.compile(@get('templateString'))
).property('templateString')
setInterval (->
@set 'templateString', @_randomTemplate()
, 3000)
templateDidChange: (->
@rerender()
).observes('template')
2. 2。
App.RotatingView = Ember.View.extend
template: (->
string = @_randomTemplate()
Ember.Handlebars.compile(string)
).property()
setInterval: (->
@set 'template', Ember.Handlebars.compile(@_randomTemplate)
@rerender()
, 3000)
3. (Using Ember.ContainerView
, don't need rerender
in this approach) 3. (使用Ember.ContainerView
,在这种方法中不需要重新rerender
)
App.RotatingView = Ember.ContainerView.extend
currentView: (->
Ember.View.create({template: Ember.Handlebars.compile(@get('templateString'))})
).property('templateString')
setInterval: (->
@set 'templateString', @_randomTemplate
, 3000)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.