淘汰赛可观察格式

Posted

技术标签:

【中文标题】淘汰赛可观察格式【英文标题】:knockoutjs observable format 【发布时间】:2014-11-05 17:04:00 【问题描述】:

我是 knockoutjs 世界的新手。我正在尝试使用 knockout.js 构建一个非常简单的单页 UI。 我的 viewModel 类中有一个名为“sentence”的可观察对象,我从 JSON 填充这个值,并使用输入文本框中的数据绑定将其显示给用户。

sentence = "我对淘汰赛的第一次体验是 0"

在 UI 中,用户还有一些可以输入值的文本框。

经验 = “好”

这些输入的值应该被替换为该句子中的编号参数。

“我对淘汰赛的第一次体验很好”

html:

          <select data-bind="options: titles, optionsText: 'title', optionsValue: 'backendName', value: selectedTitleId"></select>
          <input data-bind='text:text/>

js文件:

   var sample = function()
      var self = this;
      self.selectedTitleId = ko.observable();

      self.text = ko.computed(function () 
        self.displayText = test(self.selectedTitleId(),["hi"]); //This always throws  self.selectedTitleId() is not defined:
         // the real error is parameter[0] is undefined return parameters[0].replace(pattern, function (match, group) 

        console.log(self.displayText)
        //My intention is to return "" + self.displayText + "" to the user
        return "" + self.selectedTitleId() + ""; //This shows "World is great 0"
       ); 
 
 $.getJSON("json/queries.json", function (allData) 
    var mappedTasks = $.map(allData, function (item) 
        return new Task(item.DisplayName, item.BackendFieldName, item.QueryType)
    );
    self.titles(mappedTasks);
);

 function test() 
   return sformat.apply(this, arguments);
 
  var sformat = (function() 
     var pattern = /\\|\\|\(\d+)\/g;
      return function () 
      var parameters = arguments;
       return parameters[0].replace(pattern, function (match, group) 
         var value;
           if (match === "")
             return "";
           if (match === "")
             return "";
           value = parameters[parseInt(group, 10) + 1];
            return value ? value.toString() : "";
       );
  ;
)();

如何将此 self.selectedTitleId 作为字符串传递给该测试方法?如果我尝试将 self.selectedTitleId 分配给 var,它总是抱怨 self.selectedTitleId() 没有定义。

我的要求非常简单,我有这个可观察的 self.selectedTitleId,其中包含格式化的字符串,我试图用值替换像 0 1 这样的编号参数。就像我们在 Java 世界中看到的 String.format 一样。

对此的任何帮助深表感谢。过去几天我一直在与此作斗争。

感谢您的宝贵时间!

【问题讨论】:

self 定义在哪里? 对不起,我把我的代码片段放在一起,我错过了那行。我刚刚在我的问题中编辑了一行。 【参考方案1】:

你有几个问题:

    在它有值之前调用 observable 将返回undefined,这就是您收到错误的原因。只需将 observable 初始化为空字符串 ('') 即可避免这种情况:

    self.selectedTitleId = ko.observable('');
    

    要正确绑定到input 值,您需要改用data-bind="value: ..."text 可用于&lt;p&gt;&lt;div&gt; 等非输入元素,但由于您使用的是输入,因此您应该使用value 绑定:

    <input type="text" data-bind="value: text" />
    

    在您的 ko.computed 函数定义中,我认为只使用局部变量就足够了:

    self.text = ko.computed(function () 
        // Sidenote: you don't need to pass this function an array:
        var displayText = test(self.selectedTitleId(), "hi");
    
        return "" + displayText + "";
    ); 
    

示例: http://jsfiddle.net/4pfhfbqe/1/


更新

好吧,看起来当 AJAX 请求将填充可观察数组时,selectedTitleIdundefined。我只想在处理之前添加一个检查以查看是否定义了该 observable:

self.text = ko.computed(function () 
    if (self.selectedTitleId()) 
        var text = test(self.selectedTitleId(), "hi", "bye");
        return "" + text + "";
    
    return '';
);

【讨论】:

您好安德鲁,感谢您的回复。我仍然看到相同的参数 [0] 未定义错误。当我尝试使用 firebug 调试此脚本时,首先 console.log 打印一个空字符串。第二次打印未定义。我从你的小提琴中看到的唯一区别是我如何加载输入标题。我已经用我是如何加载值的方式更新了我的问题。 不知何故 self.selectedTitleId() 最终变成了 undefinednull。您可以使用空字符串 || 其基础值来解决错误:test(self.selectedTitleId() || '', "hi")。不知道还有什么可能导致它 @user3773712:好的,我想我看到了问题——数组值在 剔除尝试设置 selectedTitleId 之后返回。由于绑定开始时下拉列表为空,因此所选项目的值为null。您可以使用我在上面发布的解决方法来解决这个问题,或者在 sformat 函数中处理它 非常感谢 Andrew :) 实际上解决方法有所帮助。您是对的,在填充值之前,淘汰赛会尝试访问 selectedTitleId。每当我尝试调试一行时,我也会看到这个未定义的问题。有没有办法让这个 JSON 填充总是首先发生? 如果你使用 AJAX(你是)可能不会。你这样做的方式没有问题,我只是添加一些undefined 检查来保护你的代码——我更新了我的答案。

以上是关于淘汰赛可观察格式的主要内容,如果未能解决你的问题,请参考以下文章

淘汰赛,通过自定义绑定修改时未观察到可观察数组

可观察数组中的淘汰赛搜索

淘汰赛将选择绑定到动态可观察数组

淘汰赛可观察数组

淘汰赛标题不更新可观察

淘汰赛计算未使用可观察数组进行更新