2012-10-18 277 views
0

我有某種「短劃線視圖」,其中顯示了一部分項目。 該項目可能會「切換」(通過某些導航)以顯示在主插座中。到目前爲止,我沒有使用Ember的路由器/狀態管理器,但是我手動序列化/反序列化了URL,並使用window.history啓用了後退/前進和「按URL恢復」功能。 例如Ember路由器動態路由

#/dash/foo,bar 
#/dash/foo,bar,ted 

應分別顯示foo,bar和ted元素。這些項目可能會在後臺加載。因此,如果您通過書籤/直接編輯網址來恢復應用程序狀態,那麼實際上可能會在一段時間後纔會到達。

我嘗試使用Ember.Router這個東西,但我只是不明白它的工作...

我通過這個偉大的指導http://emberjs.com/guides/router_primer/讀取。 但是描述的場景總是這樣:你有一個集合視圖和一個單獨的項目視圖。但是這並不適用於我的應用程序。

在這種情況下,我有3個項目,我想選擇其中的一些顯示在插座,通過切換它們。 (通常這可以是選擇,取消選擇,切換或按表達式搜索)。選中的短劃線狀態應該被序列化爲URL,並且可以通過書籤或直接對URL進行修改。

繃實現這樣的:

<a {{action toggle name href=true}}>{{name}}</a> 

這是數據獲取和選擇邏輯如何,現在(它不工作雖然)

App.dash = Ember.Object.create({ 
    FIXTURE: [App.Item.create({ 
     name: 'foo', 
     detail: 'Some very interesting foo' 
    }),App.Item.create({ 
     name: 'bar', 
     detail: 'Bar is the root of all stuff' 
    }),App.Item.create({ 
     name: 'ted', 
     detail: 'Ted is not my name' 
    })], 
    store: Ember.A(), 
    selected: Ember.A(), 
    _items: Ember.A(), 
    watchItems: function() { 
     var items = this._items; 
     var store = this.store; 
     items.clear(); 
     this.get('selected').forEach(function (name) { 
      var item = store.findProperty('name', name); 
      items.pushObject(item); 
     }); 
    }.observes('selected', 'store'), 
    toggle: function (name) { 
     var selected = this.get('selected'); 
     var index = selected.indexOf(name); 
     if (index !== -1) { 
      selected.removeAt(index); 
     } else { 
      selected.push(name); 
     } 
     this.set('selected', selected); 
    }, 
    fetch: function() { 
     var FIXTURE = this.FIXTURE; 
     var store = this.store; 
     if (store.length == 0) { 
      Ember.run.later(function() { 
       FIXTURE.forEach(function (item) { 
        store.pushObject(item); 
       }); 
      }, 2000); 
     } 
    },   
    items: function (selected) { 
     var items = this._items; 
     items.clear(); 
     if (Ember.isArray(selected)) { 
      this.set('selected', selected); 
     } else { 
      this.set('selected', []); 
     } 
     this.fetch(); 
     return items; 
    } 
}); 

這是路由器:

App.Router = Ember.Router.extend({ 
    root: Ember.Route.extend({ 
     index: Ember.Route.extend({ 
      route: '/', 
      redirectsTo: 'dash' 
     }), 
     dash: Ember.Route.extend({ 
      route: '/dash/:selected', 
      connectOutlets: function (router, context) { 
       var selected = context && context.selected; 
       var dashItems = App.dash.items(selected); 
       router.get('applicationController').connectOutlet('dash', dashItems); 
      }, 
      deserialize: function (router, params) { 
       if (params.selected !== 'undefined') { 
        return params.selected; 
       } 
      }, 
      serialize: function (router, context) { 
       var selected = App.dash.get('selected'); 
       var hash = { 
        selected: selected 
       }; 
       return hash; 
      }, 
      toggle: function (router, event) { 
       event.preventDefault(); 
       event.stopPropagation(); 
       var name = event.context; 
       App.dash.toggle(name); 
       var selected = App.dash.get('selected'); 
       router.transitionTo('dash', { 
        selected: selected 
       }); 
      }, 
      eventTransitions: { 
       toggle: 'dash' 
      } 
     }) 
    }) 
}); 

這是完整的小提琴http://jsfiddle.net/NWfbj/1

任何幫助非常感謝!

+0

在'items' fonction,你叫' items.clear()',然後返回項目。這是你真正想要的嗎? –

+0

是的,這是預期的。項目功能應該清除當前選擇/所有顯示的項目。 this._items將填充在watchItems觀察者(異步)中。我試圖接近路由器入門http://emberjs.com/guides/router_primer/ App.Shoe.find方法。 – lipp

回答

1

好吧,我嘗試解決一些事情:

  • 在灰燼oject訪問屬性時,一個好的規則是要始終使用get(「財產」)/套(「財產」,值」 )

  • 當您想要觀察數組內容時,請使用特殊的'@each'。當數組中的任何對象被添加/移除時,觀察者將被觸發。

  • 我刪除了我認爲item()函數中額外的items.clear()。

如果你希望能夠通過URL來操作,我認爲你必須檢討反序列化方法,以此來回報您所期望的(我不知道這是否應該是字符串數組,一個項目(從存儲中檢索)的陣列,它給你:)

你可以看到我在這裏所做的:http://jsfiddle.net/Sly7/NWfbj/23/

<script type="text/x-handlebars" data-template-name='application'> 
    <h1>Dash Router App</h1> 
    {{#each App.dash.store}} 
    <a {{action toggle name href=true}}>{{name}}</a> 
    {{/each}} 
    {{outlet}} 
</script> 

<script type="text/x-handlebars" data-template-name='dash'> 
    {{#each controller}} 
    <h1>{{detail}}</h1> 
    {{/each}} 
</script> 
App = Ember.Application.create(); 
App.Item = Ember.Object.extend({ 
    name: null, 
    detail: null 
}); 

App.dash = Ember.Object.create({ 
    FIXTURE: [{ 
     name: 'foo', 
     detail: 'Some very interesting foo' 
    }, { 
     name: 'bar', 
     detail: 'Bar is the root of all stuff' 
    }, { 
     name: 'ted', 
     detail: 'Ted is not my name' 
    }], 
    store: [], 

    selected: [], 

    _items: [], 

    watchItems: function() { 
     console.log('watch items', this.get('selected')); 
     var self = this; 
     this.get('_items').clear(); 
     this.get('selected').forEach(function (name) { 
      var item = self.get('store').findProperty('name', name); 
      console.log(name); 
      self.get('_items').pushObject(item); 
     }); 
    }.observes('[email protected]', '[email protected]'), 

    toggle: function (name) { 
     var selected = this.get('selected'); 
     var index = selected.indexOf(name); 
     if (index !== -1) { 
      selected.removeObject(name); 
     } else { 
      selected.pushObject(name); 
     } 
     console.log('toggle', name, 'is now selected?', selected.indexOf(name) !== -1, selected); 
     this.set('selected', selected); 
    }, 

    fetch: function() { 
     var FIXTURE = this.get('FIXTURE'); 
     var store = this.get('store'); 
     if (store.length == 0) { 
      Ember.run.later(function() { 
       FIXTURE.forEach(function (item) { 
        store.pushObject(item); 
       }); 
      }, 2000); 
     } 
    }, 

    items: function (selected) { 
     if (Ember.isArray(selected)) { 
      this.set('selected', selected); 
     } else { 
      this.set('selected', []); 
     } 
     this.fetch(); 
     return this.get('_items'); 
    } 
}); 
App.ApplicationController = Ember.Controller.extend({}); 
App.ApplicationView = Ember.View.extend({ 
    templateName: 'application' 
}); 
App.DashView = Ember.View.extend({ 
    templateName: 'dash' 
}); 
App.DashController = Ember.ArrayController.extend({}); 

App.Router = Ember.Router.extend({ 
    enableLogging: true, 
    root: Ember.Route.extend({ 
     index: Ember.Route.extend({ 
      route: '/', 
      redirectsTo: 'dash' 
     }), 
     dash: Ember.Route.extend({ 
      enter: function() { 
       console.log('entering dash'); 
      }, 
      exit: function() { 
       console.log('exiting dash'); 
      }, 
      route: '/dash/:selected', 
      connectOutlets: function (router, context) { 
       debugger; 
       var selected = context && context.selected; 
       console.log('connectOutlets', 'selected:', selected); 
       var dashItems = App.dash.items(selected); 
       console.log('connectOutlets', dashItems); 
       router.get('applicationController').connectOutlet('dash', dashItems); 
      }, 
      deserialize: function (router, params) { 
       debugger; 
       console.log('deserialize', 'selected:', params.selected); 
       if (params.selected !== 'undefined') { 
        return params.selected; 
       } 
      }, 
      serialize: function (router, context) { 
       var selected = App.dash.get('selected'); 
       var hash = { 
        selected: selected 
       }; 
       console.log('serialize', 'selected:', selected); 
       return hash; 
      }, 
      toggle: function (router, event) { 
       debugger; 
       event.preventDefault(); 
       event.stopPropagation(); 
       var name = event.context; 
       console.log('clicked',name); 
       App.dash.toggle(name); 
       var selected = App.dash.get('selected'); 
       console.log('transitionTo', 'selected:', selected); 
       router.transitionTo('dash', { 
        selected: selected 
       }); 
      }, 
      eventTransitions: { 
       toggle: 'dash' 
      } 
     }) 
    }) 
}); 
App.initialize(); 
+0

謝謝! watchItems()。觀察('selected。@ each','store。@ each')是問題。從概念上講,我將'選擇'視爲一個屬性,但它是一個數組,這就是爲什麼觀察不起作用。 – lipp