1
數據綁定後動態綁定外部HTML文件

我一直在尋找和我發現我的有點類似的問題,但沒有相當多符合我想要做的(或至少,在解決方案沒有爲我工作)。我對杜蘭達非常陌生,所以我沒有線索可以從哪裏開始做到這一點。我工作的一個測試應用與我有一個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. 

我想知道我怎麼能設定,讓這」數據將這些實例綁定到當前視圖模型以在那裏處理。這個想法是有一個可選的文本區域(簡單的鼠標懸停突出顯示),並將其與當前選定的索引進行比較。更簡單的解釋是,它與提供句子的應用程序類似,用戶可以單擊名詞類別,然後在句子中選擇名詞。如上例所示,可選區域可以在文本中的任何位置。我已經能夠獲取它來呈現所有的HTML,但是在獲得數據綁定的工作方面一直不成功。我試過在knockout data-bind on dynamically generated elements之後嘗試應用一個ko.applyBindings(),但我會收到一個未定義的路由器錯誤,我也試過創建一個合成傳遞數據,如inserting dynamic html into durandal views,它看起來像外部html會有它擁有.js模型/視圖模型。我是否完全錯誤地進行了這個?可能過度複雜化?最初,我們把它分成了一個模型,其中每一段文本都有一個可選屬性,但它真的很笨重,打破了可觀的文檔和HMTL格式化的噩夢,所以我試圖找到一個更優雅的解決方案。我感謝您的幫助!

編輯

了以下問題在這個問題上展開: 是在訂購時需要爲它納入事件綁定在外部HTML文件中的長div標籤不是非開發人員友好誰很可能是這些文件的創造者。我目前已經通過AJAX調用獲取了html文件,然後用long div標籤替換了一個簡單的自定義'[selectable]'標籤並將其存儲在可觀察對象中,但是我仍然不確定如何將它與綁定到當前視圖。

下面是它試圖讓它工作的當前外觀。我在特別重要的行首添加了兩個星號。

的觀點:

<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上的文本。點擊主要用於當前的調試。如果他們單擊其中一個存儲桶(類別),然後單擊外部文檔中的可選區域,它將檢查數據,如果他們選擇了正確的文本選擇類別,則可以獲得積分。

以下是相關信息的視圖模型:

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'); 

    } 

鼠標懸停及移出真的只是添加和刪除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); 
     } 

    }; 

DataService是否已肉和本土豆。它加載html並用將用於數據綁定的長標籤替換[selectable]的所有匹配項。 我還沒有實現結束標記的替換,但這是一件簡單的事情。 div使用自定義屬性selectID而不是ID的原因是因爲老闆說使用ID是一個壞主意,因爲它們可以跨文檔複製,而自定義屬性不太可能發生。

和樣本文件:

[selectable] 
      &bull; This is a sample selectable area. This will be highlighted<br /> 
      when someone mouses over it. 
      <br />[/selectable] 

長的div已被替換[可選]標籤,使其更容易對人基本的HTML技能來構建一個樣本文件。

最終目標是讓創建文檔的人成爲一個易於使用的標籤,而不必嘗試粘貼長標籤並跟蹤其個人ID。我希望將鼠標事件與視圖模型綁定在一起,因爲它是完全相同的活動(並且所有文檔的分數都將統計在一起以獲得最終分數)。從用戶角度來看,當他們將鼠標放在可選文本上時,它應該只是改變顏色(簡單的jQuery)。如果他們點擊它,它會檢查他們是否選擇了正確的類別(我已經有這個工作)。我目前的問題是做文本替換,並能夠將事件綁定到視圖的功能。

回答

3

我不會使用knockoutjs html綁定。

取而代之,使用durandals組合綁定將新元素插入到dom中。 Durandal也會爲你處理綁定。

看到這篇文章: http://durandaljs.com/documentation/Using-Composition/

+0

這非常適合我。我結束了使用$ root的事件在外部HTML中的數據綁定,它的工作就像一個魅力。謝謝你的幫助,埃文! –

+0

看來我仍然有這個問題。向老闆介紹新解決方案後,他不喜歡爲了將事件綁定合併到外部html文件而需要的長div標籤。這是因爲非開發人員可能會創建這些外部文檔。我目前已經通過AJAX調用獲取了html文件,然後用long div標籤替換了一個簡單的自定義'[selectable]'標籤並將其存儲在可觀察對象中,但是我仍然不確定如何將它與綁定到當前視圖。任何想法我可以從這裏去?我很難過。 –

+0

你可以張貼一些代碼,也可以看看你想要的樣子 –