如何仅为可用键绑定Knockout viewModel?

时间:2015-02-04 07:21:34

标签: javascript c# html asp.net-mvc-4 knockout.js

我正在使用MVC中的.cshtml动态创建knockout data-bind属性。我想只绑定viewModel中可用的那些属性,我再次从restful WCF的结果动态创建。

因此,viewModel中可能存在或可能没有可用的键 例如:<span data-bind="text: cli"></span>已创建。

但是当我绑定viewModel时,我得到的错误是&#34;&#39; cli&#39;在viewModel&#34;中找不到属性。但是,我想只在第一个位置存在于viewModel中的那个键时绑定该属性。

 $(document).ready(function () {
            debugger;
            $.ajax({
                cache: false,
                type: "GET",
                async: false,
                dataType: "json",
                url: requestURL,
                success: function (data) {
                    debugger;
                    if (data.GetCircuitCheckStatusResponse.Status.HasErrors == false) {
                        networkData = data.GetCircuitCheckStatusResponse.Response.RunningStatus.networkData;
                        diagnosticData = data.GetCircuitCheckStatusResponse.Response.RunningStatus.diagnosticData;
                        diagnosticsInfo = {};
                        //To Create boxPanel Datas
                        for (var i = 0; i < networkData.length; i++) {
                            diagnosticsInfo[networkData[i].ItemTitle] = networkData[i].itemValue;
                        }
                        //To Bind the data using Knockout 
                    }
                },
                error: function (xhr) {
                    debugger;
                    alert(xhr.responseText);
                }
            });
            debugger;
            var viewModel = ko.mapping.fromJS(diagnosticsInfo);
            ko.applyBindings(viewModel);
            // Every time data is received from the server:
            //ko.mapping.fromJS(data, viewModel);

        });
@foreach (var nameValue in childContainer.NameValueImageItemsList)
                                {
                                    var cssClass = "nameValueItem floatLeft" + " " + nameValue.DataBindName;
                                    <div class="@cssClass" style="">@nameValue.DisplayName</div>
                                    <div class="@cssClass" style="width: 200px; margin-right: 10px;" ><span data-bind="text: CLI"></span></div>
                                    <div class="@cssClass" style="width: 200px; margin-right: 10px;">
                                        <a>
                                            @if (nameValue.IconImageURL != null && nameValue.IconImageURL != "")
                                            {
                                                <img src="@nameValue.IconImageURL" alt="i"/>   
                                            }
                                        </a>
                                    </div>
                                    <div class="clearBOTH"></div>
                                }

2 个答案:

答案 0 :(得分:1)

这是一种非常简单的方法:

&#13;
&#13;
ko.applyBindings({
  description: 'some description'
  // ,title: 'my title'
});
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

Description: <span data-bind="text: description"></span><br />
Title: <span data-bind="text: !!title ? title : ''"></span>
&#13;
&#13;
&#13;

相关选项可能是您在视图模型上创建safeTitle计算属性:

&#13;
&#13;
var Vm = function() {
  var self = this;
  self.description = 'my description';
  //self.title = 'my title';
  self.safeTitle = ko.computed(function() {
    return !!self.title ? self.title : '';
  });
};

ko.applyBindings(new Vm());
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

Description: <span data-bind="text: description"></span><br />
Title: <span data-bind="text: safeTitle"></span>
&#13;
&#13;
&#13;

此外,您还可以使用函数执行此操作,因此您不必为每个属性创建一个observable:

&#13;
&#13;
var Vm = function() {
  var self = this;
  self.description = 'my description';
  //self.title = 'my title';
  self.safeGet = function(prop) {
    return !!self[prop] ? self[prop] : '';
  };
};

ko.applyBindings(new Vm());
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

Description: <span data-bind="text: description"></span><br />
Title: <span data-bind="text: safeGet('title')"></span>
&#13;
&#13;
&#13;

请注意,如果这些属性是可观察的,则此代码会略有不同,如果属性可以,则会更加不同(和复杂)。

另一种选择可能是检查this blog post的第3点,包装现有的绑定:你可以创建另一个&#34;文本&#34;保护这种情况的约束力。

PS。我仔细重新考虑你的设计。很可能是属性是&#34;可选&#34;与某些领域概念有关。

PPS。您也可以考虑使用Null对象模式服务器端,这个问题完全消失了。

PPPS。这是解决问题的最后一种方法,(合乎逻辑,但是)令我惊讶的是:

&#13;
&#13;
ko.applyBindings({
  desc: 'some description'
  // ,title: 'my title'
});
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

Description: <span data-bind="text: $data.desc"></span><br />
Title: <span data-bind="text: $data.title"></span>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

这就是我的工作方式:

 <span data-bind="text: $data['@nameValue.DataBindName'] "></span>