基本的な Ember アプリケーションがあります。選択要素とテキスト フィールドの 2 つのコントロールがあります。コントロールは、表示されるデータを変更するために使用されます。select 要素を使用すると、すべての数字、偶数のみ、または奇数のみを表示するように選択できます。テキスト フィールドを使用して、入力した数字を含む数字を検索できます。
コントロールが独立して動作する必要があることを望みます。つまり、select 要素からオプションを選択した後にテキスト フィールドに入力すると、select 要素がリセットされます。同様に、select 要素からオプションを選択すると、テキスト フィールドがクリアされます。
this.set('query', '')
のオブザーバーを呼び出すと、のときにすべての数値を設定するようにプログラムされている のオブザーバーselect
がトリガーされるため、これを実装するのは難しいと思います。つまり、このアプローチでは、偶数を選択するとテキスト フィールドがクリアされ、すべての数字が表示されてしまいます。これは、偶数が選択されたため間違っています。query
content
query === ''
メソッドの値をチェックすることで、うまく機能するようになりまし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
、複数のビューを処理するためのもののようです。ここでは、ステートフル コントロールを持つビューが 1 つだけあります。
デモ: 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}}