ContainerView
他のビューを入れ替える があります。別のContainerView
ものをコンテンツとして使用します。ネストされた をスワップインしようとすると、スワップContainerView
アウトした後、エラーが発生します: Uncaught Error: assertion failed: calling set on destroyed object
。
これがフィドルです:http://jsfiddle.net/hekevintran/bFSKD/
エラーを発生させるには、「その他のフォーム」をクリックしてから、「最初のフォーム」をクリックします。
ContainerViews
エラーは、削除されたビューが破棄され、ネストされた子ビューが再作成されないためだと思いますContainerView
。この例を修正する正しい方法は何ですか?
テンプレート:
<script type="text/x-handlebars" data-template-name="box">
<div>
{{#each forms}}
<button {{action "selectForm" this }}>{{this.name}}</button>
{{/each}}
{{view container}}
</div>
</script>
<script type="text/x-handlebars" data-template-name="form">
<form>
{{#each fields}}
<div>
{{this.label}}: {{view this.widget}}
</div>
{{/each}}
</form>
</script>
JavaScript:
App = Ember.Application.create({});
App.BoxController = Ember.Object.extend({
initialForm: null,
currentForm: null,
init: function () {
var form = this.get('initialForm');
this.set('currentForm', form);
this.get('container').set('currentView', form.get('view').create());
},
forms: [],
container: function () {
return Ember.ContainerView.create({
boxController: this,
controllerBinding: 'boxController.currentForm'
})
}.property(),
selectForm: function (form) {
this.set('currentForm', form);
this.get('container').set('currentView', form.get('view').create());
}
});
App.Field = Ember.Object.extend({
value: null,
widgetBaseClass: Ember.TextField,
widget: function () {
return this.get('widgetBaseClass').extend({
field: this,
valueBinding: 'field.value'
});
}.property('widgetBaseClass')
});
App.RangeField = App.Field.extend({
widget: function () {
var field = this;
return Ember.ContainerView.extend({
childViews: [field.get('select1').create(), field.get('select2').create()]
});
}.property('select1', 'select2'),
fromValue: null,
toValue: null,
value: function () {
return [this.get('fromValue.value'), this.get('toValue.value')];
}.property('fromValue', 'toValue'),
choices: [
'1',
'2',
'3',
'4'
],
remainingChoices: function () {
var fromValue = this.get('fromValue');
if (fromValue) {
var choices = this.get('choices');
var index = choices.indexOf(fromValue);
return choices.slice(index + 1);
}
return [];
}.property('fromValue', 'choices'),
select1: function () {
return Ember.Select.extend({
field: this,
valueBinding: 'field.fromValue',
contentBinding: 'field.choices'
});
}.property(),
select2: function () {
return Ember.Select.extend({
field: this,
valueBinding: 'field.toValue',
contentBinding: 'field.remainingChoices',
contentHasChangedOnce: false,
contentChanged: function () {
// Set the initial value only once
if (! this.get('contentHasChangedOnce')) {
this.set('contentHasChangedOnce', true);
this.set('value', this.get('content')[0]);
}
// Reset the value if the chosen value is no longer
// available
if (! this.get('content').contains(this.get('value'))) {
this.set('value', this.get('content')[0]);
}
}.observes('content')
});
}.property()
});
App.Form = Ember.Object.extend({
fieldNames: [],
fields: function () {
var that = this;
var out = [];
_.each(this.get('fieldNames'), function (fieldName) {
out.pushObject(that.get(fieldName));
});
return out;
}.property('fieldNames')
});
aForm = App.Form.create({
name: 'First Form',
fieldNames: [
'a',
'b'
],
a: App.Field.create({label: 'A'}),
b: App.RangeField.create({label: 'B'}),
view: Ember.View.extend({
templateName: 'form'
})
});
var boxController = App.BoxController.create({
initialForm: aForm,
forms: [
aForm,
Ember.Object.create({
name: 'Other Form',
view: Ember.View.extend({
template: Ember.Handlebars.compile('Foobar')
})
})
]
});
var boxView = Ember.View.create({
templateName: 'box',
controller: boxController
});
boxView.append();