- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
当我对可观察数组执行推送或弹出操作时,它会反射(reflect)在用户界面中。然而,数组上的其他操作不会改变 UI 中的任何内容。这是我的案例示例:
<ul data-bind="foreach: addresses">
<!-- ko template: {name: 'AddressItemTemplate', data: {address: $data, page: 'update-page'} }-->
<!-- /ko -->
</ul>
我在两个不同的页面中使用我的模板,这就是我使用这样的模板数据的原因。
<script type="text/html" id="AddressItemTemplate">
<p data-bind="text: (page == 'update-page') ? 'updating' : 'declined'"</p>
<p data-bind="text: address.title"></p>
</script>
现在在 js 方面,ofc 我将地址声明为可观察数组
this.addresses = ko.observableArray([addresObject1, addressObject2, ...])
在页面的某个位置,我编辑了地址值。为了让 UI 反射(reflect)更改,我执行以下操作:
//suppose we know that the first address is being edited
var tmp_addresses = addresses();
tmp_addresses[0].title = 'blabla';
addresses(tmp_addresses);
就是这样,在 viewModel 中,我可以看到 addresses
的内容已更新,但在 UI 中却没有?
addresses.push(someAddressObject);
或
addresses.pop();
有效(使用新的/删除的元素更新 UI)。但 addresses.splice(0, 1, newAddressObject)
不再在 UI 中执行任何操作。
我在这里缺少什么?怎么能插入流行作品而不是其他作品呢?我在 knockout 框架中遇到了错误吗?
更新
我找到了一种方法,但有问题。我会先讲这个:
我很清楚,如果我在 observable 数组中使用 observable 对象,更改将反射(reflect)在 UI 中。然而这正是我想要避免的事情。这是一种矫枉过正的行为。
在属性真正暴露给用户交互的情况下,应该需要可观察的属性。例如,如果您有一个用于设置对象的每个字段的 UI,那么 observable 属性将是正确的调用。
但是就我而言,我什至没有用于更新地址字段的用户界面。此外,我不需要修补并不断观察所有地址的所有属性。就我而言,服务器时不时会发生更新,并且仅更改单个地址字段中的单个字段。
从另一个 Angular 来看我建议的方式应该有效。我只是立即更新整个数组,而不是单独更新每个元素。这与以下逻辑完全相同:
someObservableObject({newObject: withNewFields, ...});
这就是为什么我不需要我的对象作为可观察对象。我只是想重新声明数组并完成更改。例如,建议如果您要对可观察数组进行大量推送,请不要多次使用 array.push(...) ,而是将较大的数组重新声明到可观察数组变量上 我在我的问题中以类似的方式做到了这一点。否则,我会告诉 knockout 跟踪每个对象及其中的每个字段,这几乎不是我想要的。
现在,我终于让它工作了,但我的做法表明有一种更干净的方法来做到这一点。
我发现,可观察数组中的项目会以某种方式被跟踪,并且当您使用它们重新声明数组时不会更新它们。例如,我在问题中给出的代码将不起作用。但是下面的代码可以工作:
var tmp_addresses = addresses();
var tmp_addr = tmp_addresses[0];
var new_addr = {};
Object.keys(tmp_addr).forEach(function(key){
new_addr[key] = tmp_addr[key];
});
new_addr.title = 'Hey this is something new!'
addresses.splice(0, 1, new_addr);
不满意?下面的代码也将起作用,因为我们正在重新定义数组:
var newAddressObject1 = {...}, newAddressObject2 = {...};
addresses([newAddressObject1, newAddressObject2]);
但是下面的方法是行不通的!
var tmp_addresses = addresses();
var tmp_addr = tmp_addresses[0];
tmp_addr.title = 'Hey this address wont update';
addresses.splice(0, 1, tmp_addr);
怎么会呢?我认为 knockout 为 observableArrays 中的项目添加了一个内部属性,当我尝试重新插入一个时,它不会更新。
我的问题现在已经演变成创建一个新的对象,其属性与可观察数组中所需项目的属性相同。我上面的编码方式看起来非常肮脏。一定有更好的方法来做到这一点
最佳答案
您错误地为可观察的 title
分配了值,这就是 UI 未反射(reflect)其更改的原因(2 路绑定(bind)已损坏)。
经验法则在为 observable 赋值时始终使用 ()
表示法(保持双向绑定(bind)完整)
View 模型:
var ViewModel = function () {
var self = this;
self.addresses = ko.observableArray([{
'title': ko.observable('one')
}, {
'title': ko.observable('two')
}])
setTimeout(function () {
var tmp_addresses = self.addresses();
tmp_addresses[0].title('blabla'); //assigning data to observable
self.addresses(tmp_addresses);
}, 2000)
};
ko.applyBindings(new ViewModel());
工作样本 here
PS:不要因为使用 =
完成分配后看到 viewModel 中的值变化而被欺骗,两个绑定(bind)已损坏 UI 不会反射(reflect) VM 的更改。
当您拼接
时,您的observableArray UI会进行更改检查 here
关于javascript - KnockoutJS - UI 不使用内置的 observableArray 方法进行更新,除了 Push 和 Pop 之外,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33170683/
我有 2 个 observablearray。 当我将项目从 observablearray1 复制到 observablearray2 并更改 observablearray2 中的值时,obser
我正在使用这个名为 Dragula 的插件,它需要一个 ObservableArray 作为数据源。 HTML/Knockout 绑定(bind)
我是 JS 和 Knockout 的新手。我想将 observableArray 中的特定 observable 复制到另一个 observableArray。我怎样才能做到这一点? HTML
我在使用 Knockout.js 过滤可观察数组时遇到问题 我的js: 包含数据的数组 var docListData = [ { name: "Article Name 1", info:
我有这个模型,一个Foo有很多FooItem。如何向 FooItem 添加对象? 我有这段代码,您可以建议甚至删除最适合此场景的整个代码 var Foo = function (selected) {
我有以下 View 模型: function instance(id, FirstName){ $.extend(this, { id: ko.observable(id ||
我有这段代码,我希望渲染从 REST 查询的菜单: var PageViewModel = function() { var self = this; //
我发现这个问题与我的类似 - Replace all elements in Knockout.js observableArray 我还有另一个问题 - 如果我用新内容替换 observableAr
我正在尝试使用 knockoutJS 填充级联 select2 下拉列表。当使用静态数据时,代码似乎工作正常,如 function staticbuildData() 中所示。 ,但在使用函数 fun
knockoutjs 新手,我正在遵循有关加载和保存数据的教程,但我遇到了一些麻烦。当我将对象推送到数组时,该数组为空。我也在使用表格。这是我的代码, function Quiz(data) {
我正在开发一个项目,其中有一个搜索字段,可以根据搜索框中输入的内容过滤 observableArray。 这是我的 html 代码: 这是我的js代码: var Bu
我在客户端开发环境中工作,必须遵守他们的编码标准。我有以下 JS 和 HTML。我的 observableArray 未定义。我无法让它工作。甚至 console.logs 也打印了正确的值。 请不要
我有一个动态数据对象,因为它是从 WebApi 加载数据调用中读取的......然后使用以下方法将其转换为可观察对象: $.get("/api/PlateTemplate/Get", { id: s
我想为可观察数组中的元素设置动画。 我不会在 observableArray 中添加或删除项目。 考虑到以下 jsfiddle,我想调用 animateFirstElement 函数并突出显示行星“M
我有一个计算的可观察对象,它返回我的 observableArray 的过滤、排序版本,但排序根本不起作用。 这里是 My fiddle String.prototype.contains = fun
我想要一个 ko.observableArray 维护自己的排序顺序,其中排序顺序取决于每个项目的计算属性。 我希望它能工作: var threads = ko.observableArray().e
我有一个类似的 View 模型 AppViewModel = { agent : ko.observableArray([ { name : 'test',
我编写了简单的示例来了解 ko.observableArray 的工作原理。 **HTML**: Count is : JS: var anotherObservableArray = ko.ob
我有一个由 AJAX 调用填充的可观察数组,但它没有更新。 function ViewModel() { var self = this; self.FinanceTypes = ko
我有两个带有对象的 observableArray: self.firstHorizontalLineArr = ko.observableArray([{color: "red", val: 0},
我是一名优秀的程序员,十分优秀!