简体   繁体   English

在Ember.js中旋转视图

[英]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.

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