【问题标题】:How to get knockouts sibling data-bind properties如何获得淘汰赛兄弟数据绑定属性
【发布时间】:2014-10-14 18:45:37
【问题描述】:

更新:请参阅下面的 jsfiddle 链接

再次更新 - 请参阅更新 2

我有以下 HTML:

<button type="button" data-who="Appellant" data-bind="click: showLetter, hasFlag: { value: DeterminationLettersGenerated, flag: Enum_AppealParties.Appellee, enableIfTrue: true }">View</button>

在 showLetter 函数中,我想做这样的事情:

self.showLetter = function (model, event) {
  var flagValue = $(event.target).data("bind").flag;
  ...
}

我所说的兄弟姐妹是指绑定的实际点击事件的兄弟姐妹。我只需要得到任何能得到我的东西Enum_AppealParties.Appellee

我尝试了ko.toJSko.toJSON$.parseJSONJSON.stringify 的多种组合。他们总是给我返回以下字符串,并在其周围加上引号或转义引号:

click: showLetter, hasFlag: { value: DeterminationLettersGenerated, flag: Enum_AppealParties.Appellee, enableIfTrue: true }

我需要的是上面的字符串转换为 JSON,所以在最坏的情况下我需要在代码中执行以下操作:

self.showLetter = function (model, event) {
  var magicObject = SomeAwesomeAnserHere();
  var flagValue = magicValue.hasFlag.flag;
  ...
}

更新: 重新请求查看它的回购,请查看此链接Fiddle 只需单击其中的“查看”按钮,就会出现一些警报消息。说“应该说对象”的那个说它是一个字符串。不确定我上面提到的组合是要走的路还是什么。只想获取每个数据绑定元素。

更新 2: 我知道KO必须做我想要完成的事情,对吧?因此,在 KO 代码中进行了一些挖掘之后,我看到了它将数据绑定字符串转换为可用对象(在本例中为函数)的位置。我接近让它在我自己的绑定/函数中有用。这还不是 100% 有效。但也许有比我聪明的人在修补它......

此代码在 KO.click 事件中,如上面的 self.showLetter:

var rewrittenBindings = ko.expressionRewriting.preProcessBindings($(event.target).data("bind"), null);
var functionBody = "with($context){with($data||{}){return{" + rewrittenBindings + "}}}";
var almost = new Function("$context", "$element", functionBody);

【问题讨论】:

  • 您可以尝试创建一个repro 吗?我很确定我们可以提供帮助,但是如果没有整个设置,这有点困难。理想情况下,让问题编辑器中的 Stack Snippets 按钮旋转一下。
  • 感觉就像您以错误的方式进行此操作,而不是按照设计的工作方式使用淘汰赛。为什么你想要的属性不是 ViewModel 本身的一部分?除非在少数情况下(通常与自定义绑定有关),否则尝试将其从绑定中拉回并没有多大意义。
  • @MattBurland Enum_AppealParties 是一个全局 json 对象。成为模型的一部分不需要也没有意义。主要是因为它在许多地方和不同的模型中使用。
  • @Grandizer Matt 是对的:您本身不应该有一个全局 JSON 对象。您应该将enum 创建为必需模块,然后将其引入需要它的每个视图模型中。或者更好的是,要求它进入您的客户端数据模型。这就是我们所做的。
  • @EricTaylor,这听起来很有趣。你能说明你的意思吗?不知道如何在 javascript 中“要求”东西。作为一个模块,对我来说只是另一个导入的文件。对我来说,无论如何,这似乎又是一个全局变量。很想看看你的意思。对于我的 JS 代码来说,这可能是改变生活的一天。 ;)

标签: javascript json knockout.js


【解决方案1】:

要访问同级绑定,您需要定义一个自定义绑定。定义这样一个简单地包装 click 绑定的绑定非常简单:

ko.bindingHandlers.clickFlag = {
    init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
        ko.applyBindingAccessorsToNode(element, {
            click: function() {
                return function(model, event) {
                    valueAccessor().call(this, model, event, allBindings.get('hasFlag'));
                }
            }
        }, bindingContext);
    }
}

http://jsfiddle.net/mbest/9mkw067h/85/

【讨论】:

  • 我在撰写本文时接受的答案中添加了一个更新,以指出这一点...... Grandizer,如果没有自定义解析代码,这不是你需要的吗?
【解决方案2】:

为什么不直接将其附加到点击处理程序?

<button type="button" data-who="Appellant" data-bind="click: function() {showLetter($data,Enum_AppealParties.Appellee);}">View</button>

http://jsfiddle.net/9mkw067h/86/

不过,我同意之前的海报。这应该是模型的一部分。

【讨论】:

  • 我喜欢你在那里所做的。我的hasFlag 在启用按钮等方面做了更多代码中没有的事情,但如果我不必这样做,这是一个很好的选择。谢谢!
【解决方案3】:

在这个类似的问题中,最终没有一个好的答案就失败了:

Knockout how to get data-bind keys and value observables using element?

很明显,访问此信息的唯一方法是通过解析 data-bind 属性。这是小提琴的更新版本,展示了如何解析嵌套的绑定语句以获得所需的内容:

http://jsfiddle.net/9mkw067h/83/

这是进行解析的代码:

self.showLetter = function (model, event) {
    var binding_info = {}
    var binding_attr = $(event.target).attr("data-bind")
    var indent = false, indent_key = "";
    $(binding_attr.split(",")).each(
        function(idx, binding) {
            var parts = binding.split(":")
            var key = parts[0].trim()
            var val = parts[1].trim()
            if (val.indexOf("{") != -1) {
                binding_info[key] = {}
                indent = true
                indent_key = key
            }
            if (indent == true) {
                binding_info[indent_key][key] = val.replace("{", "").replace("}", "").trim()
            }
            else {
                binding_info[key] = val
            }
            if (val.indexOf("}") != -1) {
                indent = false
                indent_key = ""
            }
        }
    )    
    console.log(binding_info.hasFlag.flag)
}

最后,binding_info 有你想要的。

更新:

上面的链接问题略有不同,因为它从另一个视图模型和给定的 DOM 元素开始,它说,我可以获取该 DOM 元素的绑定吗?它排除了自定义绑定。但是,在这种情况下,自定义绑定已经在使用中,因此 Michael Best 的以下帖子提供了一个更简洁的答案,无需自定义解析代码,并证明我的断言是错误的,即自定义解析是唯一的方法!

【讨论】:

  • 谢谢@sifriday。我以前很怕那个。我还假设 KO 中某处的代码实际上已经在这样做了,我可以利用它而不必编写解析器。
  • 是的,我的想法完全一样,这就是为什么我花了很长时间来解决我链接到的另一个问题!我想,如果我能找到那个代码,那么(1)它会很有用,(2)我会在这个过程中学到很多关于 KO 的知识。但是我没有找到代码,甚至没有学到很多关于 KO 的新知识,只是得出结论认为它非常聪明,需要更多的研究才能弄清楚到底发生了什么。但我敢打赌,有一个选项可以调用一些内部 KO 函数来执行此操作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-28
  • 2013-12-30
  • 1970-01-01
  • 2013-02-04
  • 2018-08-06
  • 1970-01-01
相关资源
最近更新 更多