使用 KnockBack ViewModel,有没有一种方法可以从底层 Backbone 模型的方法创建一个计算的可观察对象?
Using a KnockBack ViewModel, is there a way to create a computed observable from the underlying Backbone model's methods?
使用 KnockBack ViewModel,有没有一种方法可以从底层 Backbone 模型的方法创建一个计算可观察值?
例如,在javascript中:
var MyModel = Backbone.model.extend({
validate: function () {
return this.get('name').length < 0;
}
}),
baseModel = new MyModel({name: 'foo'}),
kbViewModel = kb.viewModel(baseModel),
modelContainer = document.querySelector('#myModel');
ko.applyBindings(kbViewModel, modelContainer);
并在 Knockout 标记中:
<div id="myModel">
<div data-bind="css:{'invalid': !validate()}">
<input type="text" data-bind="value: name" />
</div>
</div>
当我尝试 运行 时,出现错误:
Unable to process binding "css: function (){return {'invalid':!validate()} }"
Message: validate is not defined
我做错了什么,还是我需要手动在 ViewModel 中创建可观察对象?
var MyModel = Backbone.Model.extend({
validate: function () {
return this.get('name').length > 0;
}
}),
MyKBViewModel = kb.ViewModel.extend({
constructor: function (model) {
kb.ViewModel.prototype.constructor.call(this, model);
this.validate = ko.pureComputed(function () {
return this.name().length > 0;
}, this);
}
}),
baseModel = new MyModel({name: 'foo', class: 'bar'}),
kbViewModel = new MyKBViewModel(baseModel),
modelContainer = document.querySelector('#myModel');
ko.applyBindings(kbViewModel, modelContainer);
jsfiddles: without observable, with observable
一点序言:Knockback 将模型置于 MVVM 中,而 Knockout 实际上只是 VVM。 Knockback 还为您提供了它们之间的一些自动同步,这很好。但是您仍然需要记住,模型和视图模型是应用程序的两个不同部分。 viewmodel 不仅仅是 Bootstrap 模型的 Knockout 副本。不要在模型中放置 viewmodel 片段。
因此您需要确定验证是视图模型行为还是模型行为。我说 viewmodel,因为你想在视图中使用它。所以从模型中删除它并定义一个计算。
但是,如果你想让它成为模型的一部分,你会想要定义一个属性,而不仅仅是一个方法,以及一个模型事件处理程序来更新变化的属性。 Knockback 会尽职尽责地将属性复制到视图模型中,您可以在那里使用它。
var MyModel = Backbone.Model.extend({
validate: function() {
this.set('isValid', this.get('name').length > 0);
},
initialize: function() {
this.validate();
this.on('change:name', this.validate);
}
}),
baseModel = new MyModel({
name: 'foo',
isValid: null
}),
kbViewModel = kb.viewModel(baseModel);
kbViewModel.validate = ko.observable();
modelContainer = document.querySelector('#myModel');
ko.applyBindings(kbViewModel, modelContainer);
.invalid {
background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.3.2/backbone.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockback/1.0.0/knockback.min.js"></script>
<div id="myModel">
<div data-bind="css:{'invalid': !isValid()}">
<input type="text" data-bind="value: name" />
</div>
</div>
使用 KnockBack ViewModel,有没有一种方法可以从底层 Backbone 模型的方法创建一个计算可观察值?
例如,在javascript中:
var MyModel = Backbone.model.extend({
validate: function () {
return this.get('name').length < 0;
}
}),
baseModel = new MyModel({name: 'foo'}),
kbViewModel = kb.viewModel(baseModel),
modelContainer = document.querySelector('#myModel');
ko.applyBindings(kbViewModel, modelContainer);
并在 Knockout 标记中:
<div id="myModel">
<div data-bind="css:{'invalid': !validate()}">
<input type="text" data-bind="value: name" />
</div>
</div>
当我尝试 运行 时,出现错误:
Unable to process binding "css: function (){return {'invalid':!validate()} }"
Message: validate is not defined
我做错了什么,还是我需要手动在 ViewModel 中创建可观察对象?
var MyModel = Backbone.Model.extend({
validate: function () {
return this.get('name').length > 0;
}
}),
MyKBViewModel = kb.ViewModel.extend({
constructor: function (model) {
kb.ViewModel.prototype.constructor.call(this, model);
this.validate = ko.pureComputed(function () {
return this.name().length > 0;
}, this);
}
}),
baseModel = new MyModel({name: 'foo', class: 'bar'}),
kbViewModel = new MyKBViewModel(baseModel),
modelContainer = document.querySelector('#myModel');
ko.applyBindings(kbViewModel, modelContainer);
jsfiddles: without observable, with observable
一点序言:Knockback 将模型置于 MVVM 中,而 Knockout 实际上只是 VVM。 Knockback 还为您提供了它们之间的一些自动同步,这很好。但是您仍然需要记住,模型和视图模型是应用程序的两个不同部分。 viewmodel 不仅仅是 Bootstrap 模型的 Knockout 副本。不要在模型中放置 viewmodel 片段。
因此您需要确定验证是视图模型行为还是模型行为。我说 viewmodel,因为你想在视图中使用它。所以从模型中删除它并定义一个计算。
但是,如果你想让它成为模型的一部分,你会想要定义一个属性,而不仅仅是一个方法,以及一个模型事件处理程序来更新变化的属性。 Knockback 会尽职尽责地将属性复制到视图模型中,您可以在那里使用它。
var MyModel = Backbone.Model.extend({
validate: function() {
this.set('isValid', this.get('name').length > 0);
},
initialize: function() {
this.validate();
this.on('change:name', this.validate);
}
}),
baseModel = new MyModel({
name: 'foo',
isValid: null
}),
kbViewModel = kb.viewModel(baseModel);
kbViewModel.validate = ko.observable();
modelContainer = document.querySelector('#myModel');
ko.applyBindings(kbViewModel, modelContainer);
.invalid {
background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.3.2/backbone.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockback/1.0.0/knockback.min.js"></script>
<div id="myModel">
<div data-bind="css:{'invalid': !isValid()}">
<input type="text" data-bind="value: name" />
</div>
</div>