[英]How do you synchronise stateful controls in an Ember view?
我有一個基本的Ember應用程序。 它有2個控件:一個選擇元素和一個文本字段。 控件用於更改可見的數據。 使用select元素,您可以選擇查看所有數字,僅查看數字,或僅查看奇數。 使用文本字段,您可以搜索包含您輸入的數字的數字。
我希望控件需要獨立運行。 我的意思是,如果我在從select元素中選擇一個選項后輸入文本字段,則應該重置select元素。 同樣,如果我從select元素中選擇一個選項,則應清除文本字段。
我發現這很難實現,因為如果我在select
的觀察者中調用this.set('query', '')
,我將觸發query
的觀察者,該觀察者被編程為在query === ''
時將content
設置為所有數字query === ''
。 換句話說,這種方法使得選擇偶數將導致文本字段清除,這將導致所有數字都可見,這是錯誤的,因為選擇了偶數!
我通過在query_changed
方法中檢查select
值來query_changed
方式。 這感覺就像一個糟糕的解決方案 我想如果有超過2個控件,這種方法會用很多if語句填充觀察者。
query_changed: function() {
var query = this.get('query');
if (query === '') {
if (this.get('select').value === '') { // <-- is there a better way?
this.set('content', this.get('numbers'));
}
} else {
var output = $.map(this.get('numbers'), function(number, i) {
if (_.string.include(number, query)) {
return number;
}
return null;
});
this.set('content', output);
}
}.observes('query')
我嘗試了其他一些想法,但它們基本上都像上面那樣。
你怎么在Ember處理這件事? 我查看了Ember.StateManager
,看起來它意味着處理多個視圖。 這里我只有一個有狀態控件的視圖。
演示: http : //jsfiddle.net/DxbeB/1/
沒有任何東西來同步控件的代碼:
App = Ember.Application.create({});
App.controller = Ember.Object.create({
numbers: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30],
contentBinding: Ember.Binding.oneWay('numbers'),
select: null,
query: null,
select_changed: function() {
if (this.get('select').value === 'all') {
this.set('content', this.get('numbers'));
}
if (this.get('select').value === 'even') {
var output = $.map(this.get('numbers'), function(number, i) {
if (number % 2 === 0) {
return number;
}
return null;
});
this.set('content', output);
}
if (this.get('select').value === 'odd') {
var output = $.map(this.get('numbers'), function(number, i) {
if (number % 2 !== 0) {
return number;
}
return null;
});
this.set('content', output);
}
}.observes('select'),
query_changed: function() {
var query = this.get('query');
if (query === '') {
this.set('content', this.get('numbers'));
} else {
var output = $.map(this.get('numbers'), function(number, i) {
if (_.string.include(number, query)) {
return number;
}
return null;
});
this.set('content', output);
}
}.observes('query')
});
App.Select = Ember.Select.extend({
content: [{label: '', value: ''}, {label: 'All numbers', value: 'all'}, {label: 'Even numbers', value: 'even'}, {label: 'Odd numbers', value: 'odd'}],
optionLabelPath: 'content.label',
optionValuePath: 'content.value'
});
App.MyView = Ember.View.extend({
controllerBinding: 'App.controller'
});
模板:
{{#view App.MyView}}
{{view App.Select selectionBinding="controller.select"}}
{{view Ember.TextField valueBinding="controller.query"}}
<p>{{controller.content}}</p>
{{/view}}
您可以觀察何時在控制器上設置odd/even filter
值然后重置query
值,反之亦然,請參閱http://jsfiddle.net/pangratz666/bWT4E/ :
把手 :
<script type="text/x-handlebars" >
{{#view App.MyView}}
{{view App.Select selectionBinding="select"}}
{{view Ember.TextField valueBinding="query"}}
<hr/>
{{#each controller.filtered}}
{{this}}
{{/each}}
{{/view}}
</script>
JavaScript :
App = Ember.Application.create({
oddFilter: function(value) {
return value % 2 === 1;
},
evenFilter: function(value) {
return value % 2 === 0;
},
queryFilter: function(query) {
return function(value) {
return (value + '').indexOf(query) !== -1;
};
}
});
App.Select = Ember.Select.extend({
prompt: 'define filter',
content: ['odd', 'even']
});
App.controller = Ember.ArrayProxy.create({
content: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30],
_queryChanged: function() {
var q = this.get('query');
if (!Ember.empty(q)) {
this.set('select', null);
}
}.observes('query'),
_selectChanged: function() {
var s = this.get('select');
if (!Ember.none(s)) {
this.set('query', null);
}
}.observes('select'),
filtered: function() {
var s = this.get('select');
var q = this.get('query');
var filter = Ember.K;
if (s === 'odd') {
filter = App.get('oddFilter');
} else if (s === 'even') {
filter = App.get('evenFilter');
} else if (!Ember.empty(q)) {
filter = App.get('queryFilter')(q);
}
return this.filter(filter, this);
}.property('select', 'query').cacheable()
});
App.MyView = Ember.View.extend({
controllerBinding: 'App.controller',
selectBinding: 'controller.select',
queryBinding: 'controller.query'
});
關於你的問題if (this.get('select').value === '') { // <-- is there a better way?
:始終通過set
和get
訪問屬性。 這確保了Ember中的Binding內容按預期工作。 此外,還有一些實用程序函數,因此可以通過Ember.empty(value)
來檢查空字符串。 請參閱博客文章: http : //code418.com/blog/2012/03/08/useful-emberjs-functions/
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.