显示元素集合,隐藏活动元素

时间:2013-01-27 04:32:39

标签: ember.js

更新自问这个问题后,我重新设计了我的UI,以便我不再需要此功能;但是,为了帮助那些最终遇到类似问题的人,我将其保持开放和积极态度。

我在模板中列出了一系列元素,每个元素都有一个链接,可以在列表右侧打开它。单击一个时,我想隐藏该元素,并在单击另一个元素时再次显示该元素。我目前的做法是在模型上将属性(活动)设置为true。这有三个原因:

  1. 这个属性实际上并不是模型模式的一部分,它只是随意的;这使它看起来像一个控制器问题(见下文为什么不起作用)
  2. 我必须首先在所有模型上将active设置为false,迫使我改变另一个路由器的模型,这可能是好的还是坏的,我不确定
  3. 在最近的PeepCode截屏视频中,他展示了使用@each.{attribute}绑定到数组中的属性;这让我觉得必须有类似的事情(比如this.set("@each.active", false))一下子设置它们
  4. 我想在控制器上使用一个方法,但似乎我不能将参数传递给Handlebars if函数中的函数。

    这是我用来呈现列表的代码:

      {{#each note in controller}}
        {{!v-- I was trying to do {{#if isCurrentNote note}} but that seems to be invalid handlebars}}
        {{#unless note.active}}
          <li class="sticky-list-item">
            {{view Ember.TextArea classNames="sticky-note" valueBinding="note.content"}}
            {{#linkTo note note classNames="sticky-permalink"}}
              ∞
            {{/linkTo}}
          </li>
        {{/unless}}
      {{/each}}
    

    以下是路线:

    App.NotesController = Ember.ArrayController.extend({
      // v-- this is what I was trying to do, but couldn't pass note in the template
      isCurrentNote: function(note){ 
        return this.get("currentNote") == note;
      }.property("currentNote")
    });
    
    App.NoteRoute = Ember.Route.extend({
      setupController: function(controller,model){
        this.modelFor("notes").forEach(function(note){
          note.set("active", false);
        });
        model.set("active", true);
      }
    });
    

    就像我说的,我的作品,但感觉不对。任何人都可以证实我的怀疑或帮助缓解我的灵魂吗?

    谢谢!

1 个答案:

答案 0 :(得分:2)

对我来说,这看起来应该主要由NotesViewNotesController存储注意选择

的内容完成

这是小提琴:http://jsfiddle.net/colymba/UMkUL/6/

NotesController将保留所有笔记和所选笔记的记录:

App.NotesController = Ember.ArrayController.extend({
  content: [],
  selectedNote: null,
  selectNote: function(id){
     var note = this.get('content').findProperty('id', id);
     this.set('selectedNote', note);
  }
});

NotesView观察相应的选择和显示/隐藏列表元素

App.NotesView = Ember.View.extend({
  templateName:  'notes',
  refresh: function(){
    var view = this.$(),
        selection = this.get('controller.selectedNote');
    if (view) {
        view.find('li').show();
        if (selection) view.find('li.note_'+selection.id).hide();
    }
  }.observes('controller.selectedNote')
});

这是Note对象,它是2个模板(在列表中或完整显示时)。 ListView 处理click事件,并将id传递给NotesController

App.Note = Ember.Object.extend({
  name: '',
  content: ''
});

App.NoteView = Ember.View.extend({
    templateName: 'note'
});

App.NoteListItemView = Ember.View.extend({
    tagName: 'li',
    templateName: 'noteListItem',
    classNameBindings: ['noteID'],
    noteID: function(){
        return 'note_' + this._context.id;
    }.property(),
    click: function(e){
        this.get('controller').selectNote(this._context.id);
    }
});
NotesView模板中

显示所有内容,如果有selectedNote,我们会再次显示Note

{{#each note in controller}}
  {{#with note}}
    {{view App.NoteListItemView}}
  {{/with}}
{{/each}}

{{#if selectedNote}}
  {{#with selectedNote}}
    {{view App.NoteView}}
  {{/with}}
{{/if}}

Routes放在一起

App.Router.map(function() {
  this.resource('notes', { path: "/notes" });
});

App.IndexRoute = Ember.Route.extend({ 
  enter: function() {
    this.transitionTo('notes');
  }
});
App.NotesRoute = Ember.Route.extend({
  model: function() {
    return [
        App.Note.create({id: 1, name: 'Milk', content: '15% fresh milk'}),
        App.Note.create({id: 2, name: 'Juice', content: 'Orange with pulp'}),
        App.Note.create({id: 3, name: 'Cereals', content: 'Kelloggs Froot Loops'}),
    ];
  },
  setupController: function(controller, model) {
      controller.set('content', model);
  },
  renderTemplate: function(controller, model) {
    this.render('notes', { outlet: 'content' });
  }
});