我有一个由ko.mapping插件创建的Knockout视图模型。
var infoNeeded = [{
"ProductPKUID":10069,
"ProductID":"SW42",
"ProductName":"Display Name of Product",
"Quantity":1,
"NeededInfo":[
{
"InfoTypeNeeded":0,
"InfoGathered":null
},
{
"InfoTypeNeeded":1,
"InfoGathered":null}]}];
infoNeeded = ko.mapping.fromJS(infoNeeded);
请注意,在此示例中,viewmodel仅包含一个产品,但它是一个可包含更多产品的数组。该视图模型正在应用于这个HTML块,这似乎正在起作用。
<div id="additionalInfoNeeded" data-bind="foreach: infoNeeded">
<span data-bind="text: ProductID"></span> - <span data-bind="text: ProductName"></span>
<span data-bind="visible: Quantity > 1, text: '(Qty: ' + Quantity + ')'"></span>
<div data-bind="foreach: NeededInfo">
<div>
Needs Info Type: <span data-bind="text: InfoTypeNeeded"></span>
<div data-bind="if: (InfoTypeNeeded() === 1)">
<species-edit params="value: $data, prodID: $parent.ProductID()"></species-edit>
</div>
</div>
</div>
</div>
注意我在那里使用custom element(种类编辑),如果数组中此产品所需的信息是infoType = 1.我希望species-edit元素从服务器中获取物种列表与此productID相关,然后允许用户从该列表中选择。然后我希望我的主视图模型能够看到所选的物种。从服务器回来的物种json看起来像这样。
[{"ID":1,"Name":"BLUE CRAB","Chosen":false},{"ID":2,"Name":"EEL","Chosen":false},{"ID":5,"Name":"INSHORE FISH","Chosen":false},{"ID":6,"Name":"OFFSHORE FISH","Chosen":false},{"ID":7,"Name":"OTHER","Chosen":false},{"ID":8,"Name":"SHARK","Chosen":false},{"ID":9,"Name":"SHRIMP OR PRAWN","Chosen":false},{"ID":12,"Name":"AMERICAN SHAD","Chosen":false},{"ID":28,"Name":"SHELLFISH(OYSTER,CLAM,MUSSEL","Chosen":false}]
这是我的物种-edit.html:
<div>
<div>What type of species will the customer attempt to take?</div>
<div>Insert species valid for product <span data-bind="text: productID"></span> here.
</div>
List of species is <span data-bind="text: data.speciesList().length"></span>
<div class="speciesList" data-bind="if: data.speciesList().length > 0">
<div class="header">
<div>Unselected</div>
<div>Selected</div>
</div>
<div data-bind="foreach: data.speciesList">
<input type="checkbox" data-bind="checked: Chosen"/>
<label data-bind="text: Name"></label>
</div>
</div>
</div>
我的物种-edit.js:
define(['knockout'],
function (ko) {
function ProductSpeciesSelectionViewModel(params) {
var self = this;
self.productID = params.prodID;
self.data = params.value;
self.data.speciesList = ko.observableArray([]);
self.data.speciesList.push({Name: "Herpdy Derp", Chosen: false});
console.debug("gonna ask for " + window.applicationBaseUrl + "AdditionalInformation/SpeciesFor/" + self.productID());
var jqxhr = $.getJSON(window.applicationBaseUrl + "AdditionalInformation/SpeciesFor/" + self.productID())
.success(function (data, status, xhr) {
console.debug(data);
self.data.speciesList.push({ Name: "Test", Chosen: false });
})
.error(function() { alert("Error in Species Grabber!"); })
.complete(function() { console.log("Fetch Complete"); });
}
return ProductSpeciesSelectionViewModel;
});
如果您注意到物种编辑视图模型,我实际上并没有使用服务器返回的物种列表。我正在使用“Herpdy Derp”硬件初始化列表,然后当getJSON调用成功时,我正在添加“测试”硬币。但是,自定义元素不显示其中任何一个。它正在接收并显示productID,并且它正在接收长度== 1(应该是2?)的列表,但不呈现列表项的任何属性。这是屏幕上的结果文本。
SW42 - Display Name of Product
Needs Info Type: 0
Needs Info Type: 1
What type of species will the customer attempt to take?
Insert species valid for product SW42 here.
List of species is 1
Unselected
Selected
我很困惑。它将speciesList视为长度为1,但不呈现一个项目。我也很困惑为什么这个列表不是length == 2,因为getJSON调用已经成功了。
这是我第一次使用自定义淘汰赛元素而且我显然没有做对。任何帮助将不胜感激。
答案 0 :(得分:0)
除了Jeff Mercado关于未关闭的parens的评论之外,第二个问题是由于在它上方的console.debug上出现错误,您的JSON调用尚未到达。你还没有定义self.PrivilegeID
修复这两件事后,结果包括两个项目
function viewModel(){
var self = this;
self.infoNeeded = ko.mapping.fromJS([
{
"ProductPKUID":10069,
"ProductID":"SW42",
"ProductName":"Display Name of Product",
"Quantity":1,
"NeededInfo":[
{"InfoTypeNeeded":0,"InfoGathered":null},
{"InfoTypeNeeded":1,"InfoGathered":null}
]
}
]);
}
ko.components.register('species-edit', {
viewModel: function(params){
var self = this;
self.productID = params.prodID;
self.data = params.value;
self.data.speciesList = ko.observableArray([]);
self.data.speciesList.push({Name: "Herpdy Derp", Chosen: false});
setTimeout(function () {
self.data.speciesList.push({ Name: "Test 2", Chosen: false });
}, 2000);
self.data.speciesList.push({ Name: "Test 1", Chosen: false });
},
template: `
<div>What type of species will the customer attempt to take?</div>
<div>
Insert species valid for product <span data-bind="text: productID"></span> here.
</div>
List of species is <span data-bind="text: data.speciesList().length"></span>
<div class="speciesList" data-bind="if: data.speciesList().length > 0">
<div class="header">
<div>Unselected</div>
<div>Selected</div>
</div>
<div data-bind="foreach: data.speciesList()">
<div style="border:1px dashed blue">
<input type="checkbox" data-bind="checked: Chosen">
<label data-bind="text: Name"></label>
</div>
</div>
</div>
`
});
ko.applyBindings(new viewModel());
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.min.js"></script>
<div id="additionalInfoNeeded" data-bind="foreach: infoNeeded">
<span data-bind="text: ProductID"></span> - <span data-bind="text: ProductName"></span>
<span data-bind="visible: Quantity > 1, text: '(Qty: ' + Quantity + ')'"></span>
<div data-bind="foreach: NeededInfo">
<div>
Needs Info Type: <span data-bind="text: InfoTypeNeeded"></span>
<div data-bind="if: (InfoTypeNeeded() === 1)"><species-edit params="value: $data, prodID: $parent.ProductID()"></species-edit></div>
</div>
</div>
</div>
&#13;
修改强>
查看pastebin链接后的主要问题似乎与加载依赖项的方式有关。您在顶部的脚本标记中加载knockout.js,然后您告诉require.js在其路径配置中单独加载knockout。所以任何使用&#39; ko&#39;在索引页面上使用的是不同的敲除实例,而不是在组件中使用ko的任何东西。