KO로 곧 시작하여 곧 프로젝트에 참여시키고 싶습니다. 여가 시간에 나는 직장에서 웹 서비스를 해왔다. 이것은 기본적으로 데이터로 무엇인가를 시작한 다음 다른 작업을하는 것으로 시작되었다. 그래서 처음에는 마약 이름 목록을 반환했습니다. 좋아, 반환 된 결과의 개수를 추가합시다. 자, 각 약물의 세부 사항을 모달로 채 웁니다. 좋아, 마약 이름을 수정합시다. 아니 진짜 운율이나 이유, 그냥 물건을 들고와 KO 놀아.observableArray에서 업데이트를 위해 데이터를 관리하는 방법을 잘 모름
어디서나 데이터를 실제로 관리 할 수있는 방법을 모르겠다. 내가 가진 것을 살펴보고 문제를 설명하는 스크린 샷을 만들었습니다.
- 은 "Y"버튼을 클릭하여 검색 결과를 얻을 . 나는 다음 약물 이름이 업데이트됩니다
- 버튼 "저장"
- 나는 약물 이름을 편집 에게
- 내가 모달 창에 그 약물에 대한 상세보기를 얻을 "야스민 (28)"약물을 선택하고 클릭 모달 창
- 나는 DOM의 해당 부분을 크롤링하고 이전 약물 이름을 신약 이름으로 바꾸어 검색 결과에서 약물 이름을 업데이트하고 약물 이름을 업데이트합니다.
이 문제는 KO의 관찰 가능한 특성을 이용하지 못합니다 ... 모달을 닫고 "Yasmin 28"약물 링크를 다시 클릭하면 모달에 " Yasmin 28 "방금 변경 한 것이 아닙니다 ("멋진 ").
내 observableArray에서 속성이 변경되면 추적하는 방법을 잘 모르겠습니다. 나는 관찰 가능한 두 개의 배열을 만들었고 하나는 검색 결과에 대한 약물 이름 목록을 보유하고 다른 하나는 약물의 세부 사항을 보유합니다. 나는 또한 현재의 약물 이름을 관찰 할 수있게 만들었습니다.
어디에서나 약물 이름을 추적하기 위해 내가해야 할 일을 설명 할 수 있습니까? 아래 코드와 JSON을 포함 시켰습니다. 이 데이터의 중복을 잡고 혼란을 야기으로
<div id="shell">
<button class="load" value="j">j</button>
<button class="load" value="k">k</button>
<button class="load" value="x">x</button>
<button class="load" value="y">y</button>
<button class="load" value="z">z</button>
<p id="loading"><img src="#{facesContext.externalContext.requestContextPath}/img/spinner.gif"/></p>
<h3 data-bind="visible: drugList().length > 0"><span data-bind="text: count" class="count"></span> records returned</h3>
<ul data-bind="foreach: drugList">
<li>
<span data-bind="text: drugName" class="results_drug_name"></span>
<a data-bind="click: $root.showDetails" href="#" class="show">show details</a>
</li>
</ul>
</div>
<!-- start modal: drug details -->
<div id="dialog" data-bind="jqDialog: {autoOpen: false, title: drugName}">
<p id="dialog_save_message" class="message_success">Changes saved successfully!!!!!!!!</p>
<table data-bind="foreach: drugListDetails" class="table" width="100%" cellpadding="0" cellspacing="0" border="1">
<tr>
<th scope="row">pdlId</th>
<td data-bind="text: pdlId"></td>
</tr>
<tr>
<th scope="row">drugName</th>
<td>
<span data-bind="text: $root.drugName" class="readonly"></span>
<input id="edit_drugname" class="edit_textfield" type="text" value="" size="35" />
<button data-bind="click: $root.editSave" class="edit_buttons save">Save</button>
<button data-bind="click: $root.editCancel" class="edit_buttons cancel">Cancel</button>
<ul class="detail_actions">
<li><a data-bind="click: $root.edit" href="#" class="edit">edit</a></li>
</ul>
</td>
</tr>
<tr>
<th scope="row">dosageFormDesc</th>
<td data-bind="text: dosageFormDesc"></td>
</tr>
<tr>
<th scope="row">strength</th>
<td data-bind="text: strength"></td>
</tr>
<tr>
<th scope="row">activeIngredient</th>
<td data-bind="text: activeIngredient"></td>
</tr>
<tr>
<th scope="row">tier</th>
<td data-bind="text: tier"></td>
</tr>
<tr>
<th scope="row">ancillaryCharge</th>
<td data-bind="text: ancillaryCharge"></td>
</tr>
<tr>
<th scope="row">preauthCode</th>
<td data-bind="text: preauthCode"></td>
</tr>
<tr>
<th scope="row">quantityLimit</th>
<td data-bind="text: quantityLimit"></td>
</tr>
<tr>
<th scope="row">prefAlternative</th>
<td data-bind="text: prefAlternative"></td>
</tr>
<tr>
<th scope="row">specialtyDrug</th>
<td data-bind="text: specialtyDrug"></td>
</tr>
<tr>
<th scope="row">partbCob</th>
<td data-bind="text: partbCob"></td>
</tr>
<tr>
<th scope="row">drugClassGroupId</th>
<td data-bind="text: drugClassGroupId"></td>
</tr>
<tr>
<th scope="row">drugClassId</th>
<td data-bind="text: drugClassId"></td>
</tr>
<tr>
<th scope="row">drugClass</th>
<td data-bind="text: drugClass"></td>
</tr>
<tr>
<th scope="row">genericInd</th>
<td data-bind="text: genericInd"></td>
</tr>
<tr>
<th scope="row">tip</th>
<td data-bind="text: tip"></td>
</tr>
</table>
</div>
<!-- end modal: drug details -->
<script>
$(function() {
$('.load').click(function() {
var $letter = $(this).attr('value');
//show spinner
$('#loading').show();
//load in drug list data
$.getJSON('/PreferredDrugList/service/preferredDrugs/' + $letter, function(data) {
//hide spinner
$('#loading').hide();
//replace drugList observableArray data
//preferredDrugs is an array of objects, each elem is an individual drug
myViewModel.drugList(data.preferredDrugs);
//replace count observable data
myViewModel.count(data.count);
});//end getJSON
});//end click
//setup modal dialog options
$('#dialog').dialog({
autoOpen: false,
closeOnEscape: true,
modal: true,
width:850,
height:500
});
});//end ondomready
//custom binding to initialize a jQuery UI dialog
ko.bindingHandlers.jqDialog = {
init: function(element) {
ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
$(element).dialog("destroy");
});
},
update: function(element, valueAccessor) {
var options = ko.toJS(valueAccessor());
if (options) {
$(element).dialog(options);
}
}
};
var myViewModel = {
count: ko.observable(), //# of records returned
drugList: ko.observableArray(), //list of drug names - an array of objects
drugListDetails: ko.observableArray(), //list of individual drug details
drugName: ko.observable(), //current drug name
//show drug details in modal
//func gets passed the current observableArray elem (the individual drug info we clicked on, this is an object)
showDetails: function(obj) {
//replace current drug name observable data
myViewModel.drugName(obj.drugName);
//replace drugListDetails observableArray data, otherwise we'll append data to the modal
myViewModel.drugListDetails([]);
//push individual drug info to details observableArray
myViewModel.drugListDetails.push(obj);
//show dialog
$('#dialog').dialog('open');
return false;
},
//edit drug from modal
edit: function(obj) {
var $edit = $('#dialog').find('td .edit'),
$currentTD = $edit.closest('td');
$currentTD.addClass('editing');
$currentTD.find('.readonly').hide();
$currentTD.find('.edit_textfield').show().select();
$currentTD.find('.edit_buttons').show();
return false;
},
//save an edit
editSave: function(obj) {
alert('TODO save back to the server');
var $saveBtn = $('#dialog').find('td .save'),
$currentTD = $saveBtn.closest('td'),
newDrugName = $('#edit_drugname').val(),
$dialog_save_message = $('#dialog_save_message');
//save new drug name to observable
myViewModel.drugName(newDrugName);
$currentTD.removeClass('editing');
$currentTD.find('.readonly').show();
$currentTD.find('.edit_textfield').hide();
$currentTD.find('.edit_buttons').hide();
$dialog_save_message.slideDown('slow', function() {
//animation complete
setTimeout(function() {
$dialog_save_message.slideUp();
}, 3000);
});
//cheat and update search results list with new drug name
$('.results_drug_name').each(function(index, elem) {
var $text = $(this).text();
if ($text === obj.drugName) {
$(this).text(newDrugName).addClass('edited');
}
});
},
//cancel an edit
editCancel: function(obj) {
var $cancelBtn = $('#dialog').find('td .cancel'),
$currentTD = $cancelBtn.closest('td');
$currentTD.removeClass('editing');
$currentTD.find('.readonly').show();
$currentTD.find('.edit_textfield').hide();
$currentTD.find('.edit_buttons').hide();
}
};
ko.applyBindings(myViewModel);
<!--what's returned from the web service-->
<pre>
{
"preferredDrugs": [(8)
{
"pdlId": 8090,
"drugName": "y-cof-dmx",
"dosageFormDesc": "Liquid",
"strength": "4MG/5ML; 15MG/5ML; 7.5MG/5ML",
"activeIngredient": "BROMPHENIRAMINE MALEATE; DEXTROMETHORPHAN HYDROBROMIDE; PHENYLEPHRINE HYDROCHLORIDE",
"tier": "OTC",
"ancillaryCharge": "NA",
"preauthCode": " ",
"quantityLimit": " ",
"prefAlternative": null,
"specialtyDrug": " ",
"partbCob": " ",
"drugClassGroupId": 74,
"drugClassId": 152,
"drugClass": "Respiratory Tract Agents » Antitussives",
"genericInd": "1",
"tip": " "
},-
{
"pdlId": 13417,
"drugName": "YASMIN 28",
"dosageFormDesc": "Tablet",
"strength": "3MG; 0.03MG",
"activeIngredient": "DROSPIRENONE; ETHINYL ESTRADIOL",
"tier": "3",
"ancillaryCharge": "AC",
"preauthCode": " ",
"quantityLimit": "28.0 tabs each 28 days",
"prefAlternative": "ethinyl estradiol/drospirenone",
"specialtyDrug": " ",
"partbCob": " ",
"drugClassGroupId": 3,
"drugClassId": 200,
"drugClass": "Hormones and Synthetic Substitutes » Contraceptives",
"genericInd": "0",
"tip": " "
},-
{
"pdlId": 24765,
"drugName": "YAZ",
"dosageFormDesc": "Tablet",
"strength": "3MG; 0.02MG",
"activeIngredient": "DROSPIRENONE; ETHINYL ESTRADIOL",
"tier": "3",
"ancillaryCharge": "AC",
"preauthCode": " ",
"quantityLimit": "28.0 tabs each 28 days",
"prefAlternative": "ethinyl estradiol/drospirenone",
"specialtyDrug": " ",
"partbCob": " ",
"drugClassGroupId": 3,
"drugClassId": 200,
"drugClass": "Hormones and Synthetic Substitutes » Contraceptives",
"genericInd": "0",
"tip": " "
},-
{
"pdlId": 2252,
"drugName": "YERVOY",
"dosageFormDesc": "Solution",
"strength": "50MG/10ML",
"activeIngredient": "IPILIMUMAB",
"tier": "NC",
"ancillaryCharge": "NA",
"preauthCode": " ",
"quantityLimit": " ",
"prefAlternative": null,
"specialtyDrug": " ",
"partbCob": " ",
"drugClassGroupId": 115,
"drugClassId": 1,
"drugClass": "Antineoplastic Agents",
"genericInd": "0",
"tip": " "
},-
{
"pdlId": 20993,
"drugName": "YERVOY",
"dosageFormDesc": "Solution",
"strength": "200MG/40ML",
"activeIngredient": "IPILIMUMAB",
"tier": "NC",
"ancillaryCharge": "NA",
"preauthCode": " ",
"quantityLimit": " ",
"prefAlternative": null,
"specialtyDrug": " ",
"partbCob": " ",
"drugClassGroupId": 115,
"drugClassId": 1,
"drugClass": "Antineoplastic Agents",
"genericInd": "0",
"tip": " "
},-
{
"pdlId": 564,
"drugName": "YF-VAX",
"dosageFormDesc": "Injection",
"strength": "0",
"activeIngredient": "YELLOW FEVER VACCINE",
"tier": "NC",
"ancillaryCharge": "NA",
"preauthCode": " ",
"quantityLimit": " ",
"prefAlternative": null,
"specialtyDrug": " ",
"partbCob": " ",
"drugClassGroupId": 79,
"drugClassId": 284,
"drugClass": "Serums, Toxoids and Vaccines » Vaccines",
"genericInd": "0",
"tip": " "
},-
{
"pdlId": 8910,
"drugName": "yodefan-nf chest congestion",
"dosageFormDesc": "Liquid",
"strength": "200MG/5ML",
"activeIngredient": "GUAIFENESIN",
"tier": "OTC",
"ancillaryCharge": "NA",
"preauthCode": " ",
"quantityLimit": " ",
"prefAlternative": null,
"specialtyDrug": " ",
"partbCob": " ",
"drugClassGroupId": 84,
"drugClassId": 155,
"drugClass": "Respiratory Tract Agents » Expectorants",
"genericInd": "1",
"tip": " "
},-
{
"pdlId": 13101,
"drugName": "YODOXIN",
"dosageFormDesc": "Tablet",
"strength": "650MG",
"activeIngredient": "IODOQUINOL",
"tier": "3",
"ancillaryCharge": "NA",
"preauthCode": " ",
"quantityLimit": " ",
"prefAlternative": "iodoquinol",
"specialtyDrug": " ",
"partbCob": " ",
"drugClassGroupId": 164,
"drugClassId": 277,
"drugClass": "Anti-infective Agents » Antiprotozoals",
"genericInd": "0",
"tip": " "
}-
],-
"count": 8
}
</pre>
</script>
왜 두 가지 약품 목록을 사용합니까? 두 가지 모두에 동일한 목록을 사용하는 것이 가장 좋은 이유는 무엇입니까? –
그건 내가 알아 내지 못하는 것입니다. 하나의 observableArray로 어떻게 작업할까요? 서버에서 JSON 데이터를로드 할 때 myViewModel.drugList (data.preferredDrugs); (foreach를 사용하여 반복 처리 할 객체의 배열) 어떻게 작동시킬 수 있습니까? myViewModel.drugList (data); 내 JSON 구조에서 더 높은 수준입니까? preferredDrugs 배열을 드릴 다운 할 수 없습니다. –