html - 动态地将 html 上的 observable 更改为另一个
问题描述
我正在尝试通过更改可见性来更新 html 上的 observable,我认为它应该更新绑定但没有发生,是否有另一种方法来更新绑定?
// This is a simple *viewmodel* - JavaScript that defines the data and behavior of your UI
function AppViewModel() {
this.isVisible = ko.observable(true);
this.counter0 = ko.observable(0);
this.counter1 = ko.observable(0);
this.counterDisplay = this.counter0;
this.add = function() {
console.log(this.counterDisplay());
const newValue = this.counterDisplay() + 1;
this.counterDisplay(newValue);
};
this.changeCounter = () => {
this.isVisible(!this.isVisible());
if(this.counterDisplay === this.counter0) {
this.counterDisplay = this.counter1;
console.log('change to counter1');
} else {
this.counterDisplay = this.counter0;
console.log('change to counter0');
}
this.isVisible(true);
}
}
// Activates knockout.js
ko.applyBindings(new AppViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<p>Counter Main: <div data-bind="text: counterDisplay, visible: isVisible"></div></p>
<button data-bind="click: add">Add</button>
<button data-bind="click: changeCounter">Change</button>
<p>Counter0: <div data-bind="text: counter0"></div></p>
<p>Counter1: <div data-bind="text: counter1"></div></p>
在示例中,主计数器正在显示计数器 0 的值,但是在单击更改按钮后,主计数器应该更改为显示 counter1 值,我认为更改可见性应该重新渲染 DOM 并绑定到 counter1 值,但是它仍然与 counter0 绑定。
解决方案
可见性绑定不影响绑定本身,它只会改变 DOM 元素的显示状态。改变绑定可以通过 using 来实现,ko.cleanNode(DOMElement)
但只有当你真的需要完全重建绑定时才应该使用它,而不是 99 次 100 的情况。
在您的情况下,更容易创建一个存储活动计数器索引的可观察对象和一个显示活动计数器值的计算对象。请参阅下面的代码。
// This is a simple *viewmodel* - JavaScript that defines the data and behavior of your UI
function AppViewModel() {
const self = this;
self.activeCounterIndex = ko.observable('0');
self.counter0 = ko.observable(0);
self.counter1 = ko.observable(0);
this.activeCounterValue = ko.computed(function(){
return self['counter'+self.activeCounterIndex()]();
});
this.add = function() {
const newValue = self['counter'+self.activeCounterIndex()]() + 1;
self['counter'+self.activeCounterIndex()](newValue);
};
this.changeCounter = () => {
if (self.activeCounterIndex() === '0') {
self.activeCounterIndex('1');
} else {
self.activeCounterIndex('0');
}
}
}
// Activates knockout.js
ko.applyBindings(new AppViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<p>Active counter (#<span data-bind="text:activeCounterIndex"></span>): <b data-bind="text: activeCounterValue"></b></p>
<button data-bind="click: add">Increment active counter</button>
<button data-bind="click: changeCounter">Swich counter</button>
<p>Counter #0: <span data-bind="text: counter0"></span></p>
<p>Counter #1: <span data-bind="text: counter1"></span></p>
推荐阅读
- spring-retry - 需要同时使用 SimpleRetryPolicy 和 TimeoutRetryPolicy,这样我就可以为重试模板设置最大尝试和超时
- sql - 仅选择列值在行之间发生变化的记录
- .net-core - 如何在 Dotnet Core 项目的生产环境中安全地管理连接字符串?
- angular - Angular Routing 在导航后删除 Route Fragment
- entity-framework-core - EF Core CosmosDb 不保存继承层次结构的子属性
- python - 如果页码超出范围,Django PageNumberPagination 自定义错误
- scala - 数据框列作为键和列数据作为值组在火花scala中按id
- angular - DevExtreme 文件上传 - 获取组件中的文件内容
- linux - 从 Linux 操作系统中获得独特的价值
- scrapy - 找不到环境 ScrapyEnvironment