[英]Dynamically binding an external html file after the data-bind in Durandal
我一直在尋找,並且我發現了一些類似於我的問題,但沒有一個與我想要做的完全匹配(或者至少,解決方案對我沒有用)。 我是Durandal的新手,所以我不知道從哪里開始實現這一目標。 我正在研究一個測試應用程序,我有一個數據綁定的div來顯示html,如下所示:
視圖上的數據綁定
<div class="active-document-text" id="document-text" data-bind="html: documentBody">
在視圖模型的javascript中,我讓它使用AJAX調用獲取外部HTML文件。 它工作正常,並正確綁定到視圖,顯示文檔。 我的問題是外部HTML也會有一個或多個數據綁定:
External.html
Lorem ipsum dolor
<div class="selectable" id="selectable-1"
data-bind="event: { click: $parent.onmouseClick }" >
sit amet, consectetur adipiscing</div> elit.
Integer nec odio. Praesent libero. Sed cursus ante dapibus diam.
Sed nisi. Nulla quis sem at nibh elementum imperdiet.
我想知道如何設置它以便它將這些實例數據綁定到當前的viewmodel以進行處理。 我們的想法是擁有一個可選擇的文本區域(簡單的鼠標懸停突出顯示),並將其與當前選定的索引進行比較。 一個更簡單的解釋是,它類似於提供句子的用戶,用戶點擊名詞類別,然后在句子中選擇名詞。 如上例所示,可選區域可以是文本中的任何位置。 我已經能夠讓它渲染所有的html,但是在使數據綁定工作方面卻沒有成功。 我已經嘗試在動態生成的元素上按照敲除數據綁定應用ko.applyBindings(),但是我會收到一個未定義的路由器錯誤,我也嘗試過創建一個組合傳遞數據,如插入動態html到durandal視圖 ,它看起來像外部HTML將擁有它自己的.js模型/ viewmodel。 我完全錯誤地采取了這種方式嗎? 或許過度復雜化了嗎? 最初,我們把它分解成一個模型,其中每個文本部分都有一個可選擇的屬性,但它真的很笨重地分解了大量的文檔和HMTL格式化的噩夢,所以我試圖找到一個更優雅的解決方案。 我感謝您的幫助!
以下問題擴展了這個問題:為了將事件綁定合並到外部html文件中所需的long div標簽對於可能是文檔創建者的非開發人員來說並不友好。 我現在再次使用AJAX調用抓取html文件然后用長div標簽替換一個簡單的自定義'[selectable]'標簽並將其存儲在一個observable中,但我仍然不確定如何將其與綁定到當前視圖。
以下是嘗試使其正常工作的當前外觀。 我在特別重要的線的開頭添加了雙星號。
風景:
<h3 data-bind="html: displayName"></h3>
<div class="document-analysis document-analysis-border">
<span class="title-bar">Analyze Documents</span>
<img src="./assets/images/arrow_minimize.jpg" class="minimize-button" />
<div class="container">
<div class="document-bar">
<span class="title">Documents to Analyze</span><br />
<img class="arrow-up" src="./assets/images/arrow_up.jpg" alt="Up Arrow" />
<div data-bind="foreach: documentData()" class="documents scroll-bar">
**<div data-bind="event: { click: function () { $parent.changeDocument($data); } }, attr: { id: 'document-' + id }" class="document">
<img data-bind="attr: { alt: title }" src="./assets/images/document_image.gif" class="document-image" />
<span data-bind="text: title" class="document-name"></span>
</div>
</div>
<img class="arrow-down" src="./assets/images/arrow_down.jpg" alt="Down Arrow" />
</div>
<div class="inner-container">
<div class="active-document">
**<!--<div class="scroll-bar text" id="document-text" data-bind="compose: { view: currentDocument().url, transition: 'entrance' }"></div>-->
**<div class="scroll-bar text" id="document-text" data-bind="compose: { view: documentFormatted, transition: 'entrance' }"></div>
<button class="submit">Submit</button>
</div>
<div data-bind="foreach: bucketData()" class="buckets">
<div data-bind="event: { click: function () { $parent.changeBucket($data); } }" class="bucket">
<img data-bind="attr: { id: 'bucket-' + id, src: image, alt: title }" src="//:0" class="bucket-image" />
<span data-bind="text: title" class="bucket-name"></span>
</div>
</div>
</div>
</div>
</div>
單擊新文檔時,第一個標記的行調用changeDocument()函數。 第二行和第三行是嘗試使外部文檔工作。 注釋掉的組合工作正常,但我必須使用長標簽以便於在mouseOver和mouseOut上突出顯示文本。 點擊主要用於此刻的調試。 如果他們單擊其中一個存儲桶(類別),然后單擊外部文檔中的可選區域,則會檢查數據,如果他們為文本選擇選擇了正確的類別,則會獲得積分。
這是相關的viewmodel信息:
var vm = {
displayName: 'Document Analysis',
currentDocument: ko.observable(docAnalysisObj.documents[0]),
documentData: ko.observableArray(docAnalysisObj.documents),
documentFormatted: ko.observable(),
$init: $init,
activate: activate,
onmouseOver: onmouseOver,
onmouseOut: onmouseOut,
mouseClick: mouseClick,
changeDocument: changeDocument,
canDeactivate: canDeactivate,
viewAttached: viewAttached
};
return vm;
function changeDocument(newDocument) {
var self = this;
// If they clicked the same document, ignore and return
if (!newDocument || (self.currentDocument() && self.currentDocument().id === newDocument.id)) {
return;
}
// Set the id selector name
var docElementSelector = '#document-' + newDocument.id;
// Remove the highlight from the previous class if it exists
if (self.currentDocument()) {
$('#document-' + self.currentDocument().id).removeClass('document-selected');
}
// Set the document to the new one
self.currentDocument(newDocument);
// Use data service to pull the html into self.documentFormatted
dataservice.getDocument(self.documentFormatted, self.currentDocument().url);
// Highlight the new current document
$(docElementSelector).addClass('document-selected');
}
mouseOver和mouseOut實際上只是在鼠標懸停在可選區域時添加和刪除CSS類。 changeDocument()是我嘗試使用以下dataservice對象加載html並處理CSS更改。
Dataservice對象:
var getDocument = function (documentObservable, url) {
documentObservable([]);
if (!url) {
console.log('Error: No url provided for document');
documentObservable('<h1>Error: Document Not Found</h1>Document source was undefined.');
return;
}
url = './app/views/' + url;
var options = {
url: url,
type: 'GET',
dataType: 'html',
cache: false,
error: queryFailed
};
return $.ajax(options)
.then(querySucceeded);
function querySucceeded(data) {
console.log('Document \'' + url + '\' retrieval succeeded.');
documentObservable(data);
var currentID = 1;
while (documentObservable().match(/\[selectable\]/g)) {
documentObservable(documentObservable().replace('[selectable]', '<div class="selectable" selectID="' + currentID + '" data-bind="event: { mouseover: function () { $root.onmouseOver(' + currentID + '); }, mouseout: function () { $root.onmouseOut(' + currentID + '); }, click: function () { $root.mouseClick(' + currentID + '); } }">'));
currentID++;
}
}
function queryFailed(jqXHR, textStatus) {
console.log('Error getting document ' + url + ': ' + textStatus);
documentObservable('<h1>Error: Document Not Found</h1>' + textStatus);
}
};
數據服務是這方面的佼佼者。 它加載html並將所有出現的[selectable]替換為將用於數據綁定的long標記。 我還沒有實現結束標簽的替換,但這很簡單。 div使用自定義屬性selectID而不是ID的原因是因為老板說使用ID是一個壞主意,因為它們可以在文檔中重復,而自定義屬性不太可能發生。
和樣本文件:
[selectable]
• This is a sample selectable area. This will be highlighted<br />
when someone mouses over it.
<br />[/selectable]
已經用[selectable]標簽替換了長div,使具有基本HTML技能的人更容易構建示例文檔。
最終,目標是為創建文檔的人提供一個易於使用的標記,而不必嘗試粘貼長標記並跟蹤其個人ID。 我想將鼠標事件與視圖模型聯系起來,因為它是完全相同的活動(並且所有文檔的點將被計算在一起以獲得最終得分)。 從用戶的角度來看,當他們將鼠標懸停在可選文本上時,它應該只是改變顏色(簡單的jQuery)。 如果他們點擊它,它將檢查他們是否選擇了正確的類別(我已經有了這個工作)。 我當前的問題是進行文本替換,並能夠將事件綁定到視圖的函數。
我不會使用knockoutjs html綁定。
而是使用durandals組合綁定以將新元素插入到dom中。 Durandal也將為您處理綁定。
請參閱此文章: http : //durandaljs.com/documentation/Using-Composition/
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.