如何仅为可用键绑定 Knockout viewModel?
How to bind Knockout viewModel for only available keys?
我正在 MVC 中使用 .cshtml 动态创建挖空 data-bind
属性。我只想绑定那些在 viewModel 中可用的属性,我再次根据 restful WCF.
的结果动态创建这些属性
所以在 viewModel 中可能有也可能没有一些可用的键
例如:<span data-bind="text: cli"></span>
已创建。
但是当我绑定 viewModel 时,我收到类似“'cli' 属性 not found in viewModel”的错误。但是,我只想绑定 属性 只有当该键首先存在于 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>
}
这是一个非常简单的方法:
ko.applyBindings({
description: 'some description'
// ,title: 'my title'
});
<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>
一个相关的选项可能是您在视图模型上创建一个 safeTitle
计算 属性:
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());
<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>
此外,您还可以使用一个函数来完成它,因此您不必为每个 属性:
创建一个可观察对象
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());
<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>
请注意,如果这些属性是可观察的,则此代码会略有不同,如果可以的话,则更加不同(和复杂)。
另一种选择可能是查看 this blog post 的第 3 点,以包装现有绑定:您可以创建另一个 "text" 绑定来防止这种情况。
PS。我会仔细重新考虑你的设计。属性 "optional" 很可能与某些领域概念有关。
PPS。您也可以考虑使用 Null Object Pattern 服务器端,这个问题就完全消失了。
PPPS。这是规避问题的最后一种方法,(合乎逻辑,但)令我惊讶的是:
ko.applyBindings({
desc: 'some description'
// ,title: 'my title'
});
<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>
这对我来说是这样的:
<span data-bind="text: $data['@nameValue.DataBindName'] "></span>
我正在 MVC 中使用 .cshtml 动态创建挖空 data-bind
属性。我只想绑定那些在 viewModel 中可用的属性,我再次根据 restful WCF.
所以在 viewModel 中可能有也可能没有一些可用的键
例如:<span data-bind="text: cli"></span>
已创建。
但是当我绑定 viewModel 时,我收到类似“'cli' 属性 not found in viewModel”的错误。但是,我只想绑定 属性 只有当该键首先存在于 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>
}
这是一个非常简单的方法:
ko.applyBindings({
description: 'some description'
// ,title: 'my title'
});
<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>
一个相关的选项可能是您在视图模型上创建一个 safeTitle
计算 属性:
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());
<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>
此外,您还可以使用一个函数来完成它,因此您不必为每个 属性:
创建一个可观察对象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());
<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>
请注意,如果这些属性是可观察的,则此代码会略有不同,如果可以的话,则更加不同(和复杂)。
另一种选择可能是查看 this blog post 的第 3 点,以包装现有绑定:您可以创建另一个 "text" 绑定来防止这种情况。
PS。我会仔细重新考虑你的设计。属性 "optional" 很可能与某些领域概念有关。
PPS。您也可以考虑使用 Null Object Pattern 服务器端,这个问题就完全消失了。
PPPS。这是规避问题的最后一种方法,(合乎逻辑,但)令我惊讶的是:
ko.applyBindings({
desc: 'some description'
// ,title: 'my title'
});
<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>
这对我来说是这样的:
<span data-bind="text: $data['@nameValue.DataBindName'] "></span>