我正在努力解决我认为真正愚蠢的问题。我正在使用'foreach'在Knockout.JS中迭代一个集合,并且需要使用集合中的变量为每个项目创建一个链接。
问题是我的url是使用视图模型中的变量动态生成的,我需要将它们与Knockout集合中的变量结合起来。
这是包含Knockout循环的块。
<div data-bind="foreach: pagedList" class="span8" style="border-bottom: 1px solid #0094ff;">
<div style="cursor: pointer;">
<p data-bind="text: hotelId"></p>
<p data-bind="text: name"></p>
<p data-bind="text: hotelRating"></p>
<p data-bind="text: propertyCategory"></p>
</div>
</div>
理想情况下,我想通过'onclick =“window.location ='方法将链接添加到父div。我已尝试使用Action.Link并通过字符串连接添加Knockout变量,因此;
<div style="cursor: pointer;" onclick="window.location="@Url.Action( "Index", "Hotel", new { regionId = Model.region.regionId, regionName = HttpUtility.UrlPathEncode(Model.region.regionNameLong.ToString().Replace(",","")).Replace("%20","-"), hotelId = " + hotelID() + ", hotelName = HttpUtility.UrlPathEncode(Convert.ToString(" + name() + ").Replace(",","")).Replace("%20","-") })"> </div>
但是这会给出一个'对象未实例化的错误'。其次,我首先尝试使用Knockout,通过'data-bind =“attr:'方法,如此;
<a href="someurl" data-bind="attr: { href: '/Region/' + '@Model.region.regionId ' + '/' + '@HttpUtility.UrlPathEncode(Model.region.regionNameLong.ToString().Replace(",","")).Replace("%20","-") ' + '/' + hotelID() + '/' + '@HttpUtility.UrlPathEncode(Convert.ToString(" + name() + ").Replace(",","")).Replace("%20","-")' }, text: hotelId()"></a>
再次没有骰子。
我知道这是混合客户端和服务器端范例,但是如果不放弃Knockout就无法想到另一种方式。
有没有人有这方面的经验?
答案 0 :(得分:1)
将来如果你创建一个问题的JSFiddle,它将会非常有用。
你的第二种方法更接近。
以下是使用自定义Knockout绑定和模板的示例:
在将JavaScript发送到客户端之前,您可以使用razor在服务器端设置值。
HTML是:
<div data-bind="template: { foreach: myItems, name: 'template-item' }" class="span8" style="border-bottom: 1px solid #0094ff;"></div>
<!-- basic template -->
<script type="text/html" id="template-item">
<p data-bind="text: hotelId"></p>
<p data-bind="text: hotelName"></p>
<p data-bind="text: hotelRating"></p>
<p data-bind="text: propertyCategory"></p>
<a data-bind="KoYourCustomBind: $data" href="#">link</a>
</script>
和JavaScript是:
// sample viewModel
var testViewModel = function(){
var self = this;
// another viewmodel property you want to use in url creation.
this.urlPart = "/ALLUSE/";
// array or list is called myItems
var iData = [new myItem("999", "Sheraton", "CAT7"), new myItem("007", "Marriott", "CAT11"), new myItem("212", "Budget Inn", "CAT00")];
this.myItems = ko.observableArray(iData);
}
var myItem = function(sHotelId, sName, sPropertyCategory) {
var self = this;
this.hotelId = sHotelId;
this.hotelName = sName;
this.hotelRating = 4; //hardcoded. only 4 star hotels here :)
this.propertyCategory = sPropertyCategory;
};
// ko bindings
ko.bindingHandlers.KoYourCustomBind = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext)
{
var item = valueAccessor();
var url = 'http://' + bindingContext.$parent.urlPart + item.hotelId + item.propertyCategory;
$(element).text(item.hotelName);
$(element).attr('href', url);
}
};
var vm = new testViewModel();
ko.applyBindings(vm);
小提琴示例依赖于jQuery和Knockout。