【问题标题】:knockout bindinq object with foreach用 foreach 淘汰 bindinq 对象
【发布时间】:2014-03-21 13:42:48
【问题描述】:
    features:[
       "attributes": {"CityName": "asdfsad", "Population":"125005"}
    ]

    features:[
       "attributes": {"FirstName": "xyz"}
    ]
    ....

我正在获取 javascript 对象中的功能并将其添加到

queryResult =ko.observableArray()

但正如您所见,属性不是数组。所以我不能用 foreach 绑定来绑定它。 特征 对象属性属性彼此不同。

<div data-bind="foreach: queryResult">
    <span data-bind="text: $data"></span>
</div>

这会在 span 元素中写入 [object Object]

<div data-bind="foreach: queryResult">
    <span data-bind="text: $data.CityName"></span>
</div>

这会在 span 元素中写入 asdfsad,但其他要素属性没有名为 CityName

的属性

【问题讨论】:

  • 您需要先了解要显示的属性。

标签: javascript jquery knockout.js


【解决方案1】:

基本上敲除 foreach 绑定用于同质数据。此外,如果 Web API 返回不均匀的集合,这也不是一个好的设计。但是如果你仍然需要这个,你可以使用自定义绑定来破解,例如:

ko.bindingHandlers.objectText = {
    update: function (element, valueAccessor, allBindingsAccessor, data) {
        var myobj = ko.utils.unwrapObservable(valueAccessor());
        if (!myobj) return;

        // dynamically extract data from the object
        var myproperty = "";
        if (myobj.CityName)
            myproperty = myobj.CityName;
        else if (myobj.FirstName)
            myproperty = myobj.FirstName;

        // if there is data, "redirect" to normal text binding
        if (myproperty)
            ko.bindingHandlers.text.update(element, function() { return myproperty; }, allBindingsAccessor, data);
    }
};

然后像这样写你的绑定:

<div data-bind="foreach: queryResult">
    <span data-bind="objectText: $data"></span>
</div>

这很丑陋,但你可以得到我希望的想法。通过这种方式,您可以将任何对象转换为任何类型的文本表示,例如,您可以找到第一个非空字符串属性,或将所有非空属性与其名称连接起来,等等。

【讨论】:

    【解决方案2】:

    假设你不关心 IEhttp://jsfiddle.net/7y48q/

    如果要支持 IE6,7,8,加载 underscore.js 并将 Object.keys(result) 替换为 _.keys(result)

    <div data-bind="foreach: { data: queryResult, as: 'result'}">
        <hr/>
        <!-- ko foreach: { data: Object.keys(result), as: 'k' }  -->
          <span data-bind="text: k"></span>: <span data-bind="text: result[k]"></span><br/>
        <!-- /ko -->
    </div>
    

    【讨论】:

      【解决方案3】:

      不确定您的问题是什么,但如果您尝试扩展所有对象,请尝试以下操作:

      HTML:

      <div id="bindingRoot">
          <div data-bind="foreach: queryResult">
              <div data-bind="crack: $data">
                  <span data-bind="text: name"></span>: <span data-bind="text: value"></span><br />
              </div>
          </div>
      </div>
      

      JavaScript:

      var model = {
          queryResult: ko.observableArray()
      };
      
      model.queryResult.push({ CityName: 'asdfsad', Population: 125005 });
      model.queryResult.push({ FirstName: 'xyz' });
      
      ko.bindingHandlers.crack = {
          init: function () {
              return ko.bindingHandlers['foreach'].init.apply(this, arguments);
          },
      
          update: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
              var value = ko.unwrap(valueAccessor()),
                  cracked = [];
      
              for (var k in value) {
                  cracked.push({ name: k, value: value[k] });
              }
      
              return ko.bindingHandlers['foreach'].update.apply(this, [element, function () { return cracked; }, allBindings, viewModel, bindingContext]);
          }
      };
      
      ko.applyBindings(model, document.getElementById('bindingRoot'));
      

      结果:

      CityName: asdfsad
      Population: 125005
      FirstName: xyz
      

      在这里演示:http://jsfiddle.net/Fng27/

      【讨论】:

        猜你喜欢
        • 2014-01-30
        • 2019-03-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-20
        相关资源
        最近更新 更多