Итак, у меня есть аккордеон, который возвращает данные при нажатии кнопки ..
Вызов нокаута работает должным образом, но иногда страница просто зависает при возврате данных .. Я буквально все перепробовал и не могу понять, почему это могло произойти, поскольку я удаляю массив каждый раз перед вызовом ... Есть идеи?
HTML говорит, что ошибок нет, а также javascript в инструменты google dev ...
HTML
<section id="results" style="margin-top: 1em;">
<div id="accordion">
<div class="card">
<div class="card-header" id="headingOne">
<table class="table table-striped table-hover">
<thead>
<tr>
<th>Set Next</th>
<th>Name</th>
<th>Bench</th>
<th>Transacted</th>
@*<th>Receipe Name</th>*@
</tr>
</thead>
<tbody data-bind="foreach: Stages">
<tr >
<td data-bind="css: CellClass">
<button class="btn btn-warning" data-bind="attr: {'data-id': Id}" onclick="saveStepId(this);" data-toggle="modal" data-target="#moveReason">@Html.LocalisedStringFor(model => model.MoveToStageText)</button>
<a class="text" data-bind="attr: {'data-id': Id}" data-toggle="modal"><span>@Html.LocalisedStringFor(model => model.CurrentPositionText)</span></a>
</td>
<td class="accordion-toggle" data-toggle="collapse" aria-expanded="false" data-bind="attr: {'data-target': '#' + RecipeName(), 'aria-controls': '#' + RecipeName()}, click: $root.GetRecipeHeader.bind(this, RecipeName())">
<!-- ko if: IsNext()-->
<svg width="1em" data-bind="if: RecipeName" height="1em" viewBox="0 0 16 16" class="bi bi-chevron-down" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z" />
</svg>
<!--/ko-->
<!-- ko if: IsNext() === 'False'-->
<!--/ko-->
<span data-bind="text: ProcessName"></span>
</td>
<td><span data-bind="text: BenchName"></span></td>
<td><span data-bind="text: TransactionStatus"></span></td>
</tr>
<!-- ko if: IsNext() -->
<tr id="" class="collapse" data-bind="attr: {'id':RecipeName}" data-parent="#accordion">
<td colspan="5">
<div class="accordion-inner" >
<ul data-bind="foreach: $parent.RecipeStages">
<li>
<!--ko if: CanMove()-->
<button class="btn btn-warning moveRecipeStep" onclick="saveRecipeId(this);" id="blah" data-bind="attr: {'data-id': StepId, data_recipe_name: $parent.RecipeName}" data-toggle="modal" data-target="#moveRecipeReason">@Html.LocalisedStringFor(model => model.MoveToStageText)</button>
<svg width="2em" height="2em" viewBox="0 0 16 16" class="bi bi-arrow-left-short" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M7.854 4.646a.5.5 0 0 1 0 .708L5.207 8l2.647 2.646a.5.5 0 0 1-.708.708l-3-3a.5.5 0 0 1 0-.708l3-3a.5.5 0 0 1 .708 0z" />
<path fill-rule="evenodd" d="M4.5 8a.5.5 0 0 1 .5-.5h6.5a.5.5 0 0 1 0 1H5a.5.5 0 0 1-.5-.5z" />
</svg>
<!--/ko-->
<span data-bind="text: StepName"></span>
</li>
</ul>
</div>
</td>
</tr>
<!--/ko-->
</tbody>
</table>
</div>
</div>
</div>
</section>
Modals
<section id="hidden">
<div class="modal fade" id="moveReason" tabindex="-1" role="dialog" arial-labelledby="moveReasonLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="moveReasonLabel">What is the reason for the Step move?</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body reasonDialog">
<form>
<div class="form-group">
@Html.LabelFor(model => model.ReasonText)
@Html.TextAreaFor(model => model.ReasonText, new { rows = 4, @class = "form-control", maxlength = "100", data_bind = "value: Reason" })
</div>
</form>
</div>
<div class="modal-footer">
<button id="DoMove" type="button" class="btn btn-primary">@Html.LocalisedStringFor(model => model.SubmitText)</button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="moveRecipeReason" tabindex="-1" role="dialog" arial-labelledby="moveReasonLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="moveReasonLabel">What is the reason for the Recipe move?</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body reasonDialog">
<form>
<div class="form-group">
@Html.LabelFor(model => model.ReasonText)
@Html.TextAreaFor(model => model.ReasonText, new { rows = 4, @class = "form-control", maxlength = "100", data_bind = "value: Reason" , id = "blah" })
</div>
</form>
</div>
<div class="modal-footer">
<button id="DoMoveRecipe" type="button" class="btn btn-primary">@Html.LocalisedStringFor(model => model.SubmitText)</button>
</div>
</div>
</div>
</div>
</section>
knockout.ks
self.GetRecipeHeader = function(sRecipeName) {
self.RecipeStages.removeAll();
var sSerialNumber = self.SerialNumber().trim();
var newUrl =
'@Html.Raw(Url.Action("GetRecipeData", new {serialNumber = "SERIALNUMBER", recipeId = "RECIPEID", userLevel = 0}))'
.replace("SERIALNUMBER", sSerialNumber).replace("RECIPEID", sRecipeName);
$.getJSON(newUrl).done(function (returnData) {
for (var stagepos = 0; stagepos < self.Stages().length; stagepos++) {
var stage = self.Stages()[stagepos];
//alert("RecipeName =" + stage.RecipeName() + "And sRecpeName =" + sRecipeName
// );
if (stage.RecipeName() === sRecipeName && stage.RecipeStages().length === 0) {
//alert("blah de blah");
if (returnData !== null && returnData.RecipeStages !== null) {
for (var recipepos = 0; recipepos < returnData.RecipeStages.length; recipepos++) {
self.RecipeStages.push(new recipeStepDetail(returnData.RecipeStages[recipepos].StepId,
returnData.RecipeStages[recipepos].StepName, returnData.RecipeStages[recipepos].CanMove
));
}
}
}
}
}) .fail(function (xhr, status) { alert(status); });
};
};
, а также другой функция
$("#DoMove, #DoMoveRecipe").click(function (e) {
var input = $(this);
var buttonId = input.attr("id");
var id = input.data("id");
var url = buttonId === 'DoMove' ? '@Url.Action("MakeNext")' : '@Url.Action("MoveRecipePosition")';
//$("#moveReason").modal("toggle");
if (buttonId === "DoMove") {
$.ajax(url,
{
data: {
"Id": stepId,
"Reason": $("#moveReason .reasonDialog textarea").val(),
},
cache: false,
method: "POST",
}).done(function (returnData) {
$("#moveReason").modal('hide');
self.Stages.removeAll();
self.GetData(self.SerialNumber);
//if (returnData) {
// if (returnData.BrokenRule !== null) {
// alert(returnData.BrokenRule.Message);
// } else if (returnData.ProcessStep !== null) {
// var bFound = false;
// //Done like this because you can only move backwards. Originally the logic was fuller but, most things don't change now.
// //The extra logic just hides everything past the active one
// for (var pos = 0; pos < viewModel.Stages().length; pos++) {
// if (bFound) {
// viewModel.Stages()[pos].Id(-1);
// viewModel.Stages()[pos].IsNext(false);
// } else if (viewModel.Stages()[pos].Id() == returnData.ProcessStep.Id) {
// viewModel.Stages()[pos].IsNext(returnData.ProcessStep.IsNext);
// viewModel.Stages()[pos].BenchId(returnData.ProcessStep.BenchId);
// viewModel.Stages()[pos].BenchName(returnData.ProcessStep.BenchName);
// viewModel.Stages()[pos].IsTransacted(returnData.ProcessStep.IsTransacted);
// viewModel.Stages()[pos].RecipeName(returnData.ProcessStep.RecipeName);
// bFound = true;
// }
// }
// }
//}
}).fail(function(xhr) {
try {
console.log(xhr.statusText);
console.log(xhr.responseText);
alert(xhr.statusText + "\r\n" + xhr.responseText);
} catch (ex) {
console.log(ex);
alert(ex);
}
});
} else {
self.RecipeStages.removeAll();
$.ajax(url,
{
data: {
"SerialNumber": viewModel.SerialNumber(),
"Message": $("#moveRecipeReason .reasonDialog textarea").val(),
"StepId": recipeStepId
},
cache: false,
method: "POST"
}).done(function (returnData) {
$("#moveRecipeReason").modal('hide');
self.GetRecipeHeader(recipeName);
// for (var pos = 0; pos < viewModel.RecipeStages().length; pos++) {
//if (viewModel.RecipeStages()[pos].RecipeName && viewModel.RecipeStages()[pos].RecipeName == recipeName) {
//alert(recipeName);
//}
//}
if (returnData) {
if (returnData.BrokenRule !== null) {
alert(returnData.BrokenRule.Message);
} else if (returnData.recipePosition !== null) {
var bFound = false;
//Done like this because you can only move backwards. Originally the logic was fuller but, most things don't change now.
//The extra logic just hides everything past the active one
for (var pos = 0; pos < viewModel.Stages().length; pos++) {
//if (viewModel.Stages()[pos].RecipeName() !==
// returnData.recipePosition.RecipeName)
// continue;
for (var innerPos = 0;
innerPos < viewModel.Stages()[pos].RecipeStages().length;
innerPos++) {
var recipeStage = viewModel.Stages()[pos].RecipeStages()[innerPos];
if (bFound) {
recipeStage.StepId(-1);
recipeStage.IsNext(false);
} else if (viewModel.Stages()[pos].Id() === returnData.ProcessStep.Id) {
//recipeStage.StepId(-1);
//recipeStage.IsNext(true);
viewModel.Stages()[pos].RecipeName(returnData.ProcessStep.StepName,
returnData.ProcessStep.CanMove);
bFound = true;
}
}
}
}
}
}).fail(function(xhr) {
try {
console.log(xhr.statusText);
console.log(xhr.responseText);
alert(xhr.statusText + "\r\n" + xhr.responseText);
} catch (ex) {
console.log(ex);
alert(ex);
}
});
}
})
});