[英]Ember Router dynamic route
我有某種“破折號視圖”,其中顯示了部分項目。 該項目可能會“切換”(通過某種導航)以顯示在主插座中。 到目前為止,我沒有Ember的Router / StateManager東西,而是手動對URL進行序列化/反序列化,並使用window.history啟用后退/轉發和“按URL還原”功能。 例如
#/dash/foo,bar
#/dash/foo,bar,ted
應該分別顯示foo,bar和ted元素。 這些項目可能會在后台延遲加載。 因此,如果您通過添加書簽/直接編輯URL來恢復應用狀態,則這些項目實際上可能會在一段時間后到達。
我嘗試使用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
任何幫助都非常感謝!
好吧,我嘗試解決一些問題:
訪問Ember對象中的屬性時,一個好的規則是始終使用get('property')/ set('property',value')
當您要觀察數組內容時,請使用特殊的“ @each”。 然后在添加/刪除數組中的任何對象時觸發觀察者。
我刪除了我認為在items()函數中多余的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('selected.@each', 'store.@each'),
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();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.