- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在开发网络应用程序时遇到了一些问题。需要从 knockout 外部(或者更确切地说,在 .js 文件中)访问在 foreach
绑定(bind)中使用的 knockout.js 数组。现在,ko.dataFor()
和 ko.contextFor()
允许我访问数组特定元素的上下文和数据,但不能访问数组本身。
我基本上需要的是能够扫描整个数组(所有元素)以获取其中一个属性的值,并在发出请求时通过 AJAX 将所有存在的属性发送到服务器,以便“过滤掉”那些已经存在的,使它成为多个数组条目的唯一选择器,如果这有意义的话。
我很确定答案就在上述函数中的某个地方,但我似乎找不到它。
外部脚本需要访问保存用于绑定(bind)的元素的可观察数组,或者了解从 View 模型的根开始到该数组的路径。我无法使用 subscribe
获取数据信息,因为我不知道要订阅什么。模型是动态的,本例中的示例数组即使存在,也会嵌套 3 层。它本身也在循环中,因此它的路径根据访问的 html 元素而变化,例如,它在父循环中的索引可能不同。我唯一的入口点是绑定(bind)的元素。
查看示例以更好地理解。
var VM = {};
var data = {
exampleArray: [{
key: 1,
value: 'foo1'
},
{
key: 2,
value: 'foo2'
},
{
key: 3,
value: 'foo3'
}
],
lookup: [{
key: 1,
value: 'foo1'
},
{
key: 2,
value: 'foo2'
},
{
key: 3,
value: 'foo3'
},
{
key: 4,
value: 'foo4'
},
{
key: 5,
value: 'foo5'
}
]
}
ko.mapping.fromJS(data, {}, VM);
ko.applyBindings(VM);
function addRow() {
var select = document.getElementById('selector');
var value = select.options[select.selectedIndex].value;
var text = select.options[select.selectedIndex].text;
VM.exampleArray.push({
key: ko.observable(value),
value: ko.observable(text),
})
}
#container {
width: 300px;
margin-bottom: 10px;
}
#container>div {
border: solid 1px green;
min-height: 15px;
padding: 3px;
margin: 3px;
}
select {
width: 200px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.js"></script>
<div id="container" data-bind="foreach: exampleArray">
<div>
<span data-bind="text: key() + ' - '"></span>
<span data-bind="text: value"></span>
</div>
</div>
<select id="selector" data-bind="options: lookup,
optionsText: 'value',
optionsValue: 'key'
"></select>
<button onclick="addRow();">Add a row</button>
<p> Now imagine that the lookup data set is updated from the server via AJAX call every time a row is added, where it would need to send only the rows that are not already present in this data set, making this a unique selection. I would need a way to send keys already selected to the server, so that SQL can filter out what data to send back and what data to skip. <br><br>
<b>How would i get this information?</b><br><br>
P.S. I need a way to send an array of keys, not the whole model or data-set or whatever inventive solution might be, because this is an oversimplifed example, the real model is deep nested and much more complex, and pretty much inaccessible/untouchable in the heirarchy of the app's classes that make it. If you need clerification as to why, post a comment and I will try to answer as briefly as possible.</p>
var VM = {};
var data = {
some: {
super: [
{
deep: {
nested: {
shit: {
articles: [
{key: 1, value: "fish"},
{key: 2, value: "fruit"},
{key: 3, value: "meat"},
],
}
}
}
}
],
lookup: [
{key: 1, value: "fish"},
{key: 2, value: "fruit"},
{key: 3, value: "meat"},
{key: 4, value: "eggs"},
{key: 5, value: "bread"},
{key: 6, value: "milk"},
{key: 7, value: "water"},
]
}
}
ko.mapping.fromJS(data, {}, VM);
ko.applyBindings(VM);
document.getElementById('sayt').addEventListener('focus', function(){
document.getElementById('saytResults').style.display = "block";
})
document.getElementById('sayt').addEventListener('blur', function(){
document.getElementById('saytResults').style.display = "none";
})
function printListItemContextData(btn){
console.log(ko.contextFor(btn.parentNode.getElementsByClassName('selectedArticles')[0].children[0]));
}
#sayt, #saytResults{
width: 200px;
}
#saytResults > div {
border: solid 1px black;
padding: 2px;
width: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.min.js"></script>
<div data-bind="foreach: some.super">
<div class="selectedArticles" data-bind="foreach: deep.nested.shit.articles">
<div data-bind="text: key() + ' - ' + value()"></div>
</div>
<p>Imagine that the input control below is a "full text search" of the articles on the database. As you type, a request is sent to the server with your typed text as a parameter for the query, results get delivered into the lookup dataset.</p>
<input id="sayt" type="text" value="Click here to simulate request">
<div id="saytResults" style="display: none;" data-bind="foreach: $root.some.lookup">
<div data-bind="text: key() + ' - ' + value()"></div>
</div>
<br>
<p>
The goal however is to NOT display elements that are already present in the dataset. But I cannot get to that data set, I have no idea how to "target" the array. The button below can 'print' the info (console.log) of any of the elements already in the list, but not the list itself.
</p>
<button onclick="printListItemContextData(this)"> PRINT </button>
<p>The issue is, parent context is not created as you go deep down the tree, and $parent of an element of a <b>foreach</b> is not the array it is in, but rather an object, 3 levels up.</p>
</div>
最佳答案
如果您知道您的数据是一个数组,并且该数组的每个元素都有一个子 DOM 节点,则可以通过迭代子节点并从每个子节点获取 dataFor
来重建该数组。附加的代码片段就是这样做的。
更新:调整代码,因此每个元素有多少个子节点并不重要。
var VM = {};
var data = {
some: {
super: [
{
deep: {
nested: {
shit: {
articles: [
{key: 1, value: "fish"},
{key: 2, value: "fruit"},
{key: 3, value: "meat"},
],
}
}
}
}
],
lookup: [
{key: 1, value: "fish"},
{key: 2, value: "fruit"},
{key: 3, value: "meat"},
{key: 4, value: "eggs"},
{key: 5, value: "bread"},
{key: 6, value: "milk"},
{key: 7, value: "water"},
]
}
}
ko.mapping.fromJS(data, {}, VM);
ko.applyBindings(VM);
document.getElementById('sayt').addEventListener('focus', function(){
document.getElementById('saytResults').style.display = "block";
})
document.getElementById('sayt').addEventListener('blur', function(){
document.getElementById('saytResults').style.display = "none";
})
function printListItemContextData(btn){
const el = btn.parentNode.getElementsByClassName('selectedArticles')[0];
const data = [];
for (const c of el.children) {
data[ko.contextFor(c).$index()] = ko.dataFor(c);
}
console.log("Data:", ko.toJS(data));
}
#sayt, #saytResults{
width: 200px;
}
#saytResults > div {
border: solid 1px black;
padding: 2px;
width: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.min.js"></script>
<div data-bind="foreach: some.super">
<div class="selectedArticles" data-bind="foreach: deep.nested.shit.articles">
<div data-bind="text: key() + ' - ' + value()"></div>
</div>
<p>Imagine that the input control below is a "full text search" of the articles on the database. As you type, a request is sent to the server with your typed text as a parameter for the query, results get delivered into the lookup dataset.</p>
<input id="sayt" type="text" value="Click here to simulate request">
<div id="saytResults" style="display: none;" data-bind="foreach: $root.some.lookup">
<div data-bind="text: key() + ' - ' + value()"></div>
</div>
<br>
<p>
The goal however is to NOT display elements that are already present in the dataset. But I cannot get to that data set, I have no idea how to "target" the array. The button below can 'print' the info (console.log) of any of the elements already in the list, but not the list itself.
</p>
<button onclick="printListItemContextData(this)"> PRINT </button>
<p>The issue is, parent context is not created as you go deep down the tree, and $parent of an element of a <b>foreach</b> is not the array it is in, but rather an object, 3 levels up.</p>
</div>
关于javascript - 从数据绑定(bind)外部引用 knockout 数组并且没有路径知识,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48400487/
积累和总结,是长期持续的过程 01 最近,很多朋友微信私聊关于「 butte-java-note 」仓库的话题; 这个「 Git仓库 」每年都会
我即将参加挑战测试,所以我不必参加数据库处理类(class)。尽管在过去的 5 年里我一直在使用数据库,但我还是忍不住对测试感到紧张。这是 50 个问题,有 2 部分:真/假部分和我实际编写 SQL
我的 groovy 代码将 Rabbit Native Plugin 用于 grails: def handleMessage(def body, MessageContext context) {
我想看看是否有人可以就我在 .NET 环境中的进一步知识提供任何建议... 这里有一点背景。我上了一所大学并获得了计算机科学学士学位(主要从事 C、Java 和 C++ 方面的工作)。大学毕业后在一家
我在 postgres 数据库中有一个表,该表用于测试环境,我们需要一次添加和删除多个列。问题是 postgres 最多有 1600 列,并且这个计数包括丢弃的列。我的表永远不会有 1600 个“未丢
作为业余程序员 3 年(主要是 Python 和 C)并且从未编写过超过 500 行代码的应用程序,我发现自己面临两个选择: (1) 学习数据结构和算法设计的基本知识,使我成为一名 l33t 计算机科
有人能告诉我为什么 Android 工作需要 Linux 知识吗?许多 Android 工作都以 Linux 作为先决条件。我可以很好地从 Windows 机器开发 Android 应用程序吗? 最佳
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
关闭。这个问题是off-topic .它目前不接受答案。 想改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 关闭 10 年前。 Improve thi
是否可以在 Drools 中保持知识 session ?如果是这样,如何? 我将事实存储在数据库中,并且每次添加新事实时,我都希望避免在新 session 中重新加载所有事实。 目前,当有新事实时,该
我对 C++ 有很好的了解,但从未深入研究 STL。我必须学习 STL 的哪一部分才能提高工作效率并减少工作中的缺陷? 谢谢。 最佳答案 I have good knowledge of C++ 恕我
关闭。这个问题是opinion-based .它目前不接受答案。 想要改进这个问题? 更新问题,以便 editing this post 可以用事实和引用来回答它. 关闭 9 年前。 Improve
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,
关闭。这个问题是opinion-based .它目前不接受答案。 想要改进这个问题? 更新问题,以便 editing this post 可以用事实和引用来回答它. 关闭 7 年前。 Improve
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
在我从 SO answers here 和许多 BackBoneJs 示例中选择的示例之一中,我看到初始化函数知道模型将使用哪个 View 进行渲染。我不知道我现在有点偏见,这是一个好的做法还是取决于
关闭。这个问题是off-topic .它目前不接受答案。 想改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 关闭 12 年前。 Improve thi
我在我的网站上使用 C# 和 ASP.NET MVC 3 实现 OpenID 和 OAuth。我基于 DotNetOpenAuth用于后端和openid-selector对于前端。 我喜欢 openi
很长一段时间以来,我都在思考和研究C语言编译器以汇编形式的输出,以及CPU架构。我知道这对你来说可能很愚蠢,但在我看来有些东西是非常无效的。如果我错了,请不要生气,我不明白所有这些原则是有原因的。如果
我有一些 Python 知识,但我从来不认为自己对这门语言特别流利。我正在开发一个潜在的机器视觉项目,该项目将从 SimpleCV 中受益匪浅,但从时间的角度来看,我宁愿不必非常流利地使用 pytho
我是一名优秀的程序员,十分优秀!