1

Я искал и нашел несколько похожих вопросов для себя, но ни один из них не соответствует тому, что я пытаюсь сделать (или, по крайней мере, решения для меня не работали). Я действительно новичок в Durandal, поэтому у меня мало подсказки, с чего начать это. Я работаю над приложением тестирования и у меня есть DIV, который с привязкой к данным для отображения HTML следующим образом:Динамическое связывание внешнего html-файла после привязки данных в Durandal

Data-привязку на View

<div class="active-document-text" id="document-text" data-bind="html: documentBody"> 

В JavaScript для просмотра модели , Я получаю его внешний HTML-файл с использованием вызова AJAX. Он отлично работает и правильно привязывается к представлению, отображая документ. Моя проблема заключается в том, что внешний 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. 

мне интересно, как я мог настроить его так, что он» ll - привязать эти экземпляры к текущей модели представления, которую нужно обработать. Идея состоит в том, чтобы выбрать выделенную область текста (простое подсветку указателя мыши) и сравнить ее с текущим выбранным индексом. Более простое объяснение заключается в том, что он будет похож на приложение, которое предоставило предложение, и пользователь нажмет на категорию существительных, а затем выберет существительное в предложении. Как показано в примере выше, выбираемая область может быть где угодно в тексте. Я смог получить его, чтобы отобразить все html, но не удалось получить привязку данных к работе. Я попытался применить ko.applyBindings() после него как knockout data-bind on dynamically generated elements, но я бы получил неопределенную ошибку маршрутизатора, я также попытался создать составную часть данных, таких как inserting dynamic html into durandal views, и похоже, что внешний html будет иметь собственная модель .js/viewmodel. Неужели я об этом совершенно не так? Может быть, это слишком усложняет? Первоначально у нас это было разбито в модели, где каждый раздел текста имел свойство выбора, но это действительно неуклюжий разрыв важных документов и кошмар форматирования HMTL, поэтому я пытаюсь найти более элегантное решение. Я ценю вашу помощь!

EDIT

Следующая проблема расширяется по этому вопросу: Долгий DIV тег, который требуется для того, чтобы включить привязки событий во внешнем HTML файл не является дружественным для не-разработчиков, скорее всего, будут создателями документов. В настоящее время я получил его html-файл с вызовом AJAX, а затем заменил простой пользовательский тег «[selectable]» длинным тегом div и сохранил его в наблюдаемом, но я все еще не уверен, как его включить привязки к текущему виду.

Вот текущий взгляд на попытку заставить его работать. Я добавил двойные звездочки к началу особенно важных строк.

Взгляд:

<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() - моя попытка загрузить html с использованием следующего объекта dataservice и обработать изменения 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 вместо идентификатора, заключается в том, что босс говорит, что использование идентификаторов - это плохая идея, поскольку они могут быть дублированы в документе, тогда как пользовательский атрибут с меньшей вероятностью произойдет.

И документ примера:

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

Длинные дивы были заменены тегами [выбираемых], чтобы сделать его проще для кого-то с основными HTML навыков для построения образца документа.

В конечном счете, цель состоит в том, чтобы дать человеку, создавшему документ легкий тег для работы, вместо того, чтобы пытаться вставить длинный тег и отслеживать его индивидуальный идентификатор. Я хочу, чтобы события мыши были привязаны к viewmodel, так как это все та же деятельность (и точки для всех документов будут подсчитываться вместе для окончательного результата). С точки зрения пользователя, когда они курсируют над выбираемым текстом, он должен просто менять цвет (простой jQuery). Если они нажмут на него, он проверяет, выбрана ли у них подходящая категория (у меня уже есть эта работа). Моя текущая проблема заключается в замене текста и возможности привязки событий к функциям представления.

ответ

3

Я бы не использовал привязку hock для knockoutjs.

Вместо этого использовать durandals составляют привязку для вставки новых элементов в dom. Durandal будет обрабатывать привязки для вас тоже.

Смотрите эту статью: http://durandaljs.com/documentation/Using-Composition/

+0

Это работало отлично для меня. Я закончил использование $ root с событием привязкой данных во внешнем HTML, и он работал как шарм. Спасибо тебе за помощь, Эван! –

+0

Кажется, у меня все еще есть проблемы с этим. После представления нового решения боссу ему не понравился длинный тег div, который требуется для того, чтобы он включал привязки событий во внешний html-файл. Это связано с тем, что не-dev, вероятно, создаст эти внешние документы. В настоящее время я получил его html-файл с вызовом AJAX, а затем заменил простой пользовательский тег «[selectable]» длинным тегом div и сохранил его в наблюдаемом, но я все еще не уверен, как его включить привязки к текущему виду. Любая идея, где я могу идти отсюда? Я в тупике. –

+0

можете ли вы разместить какой-либо код, пожалуйста, а также то, что вы хотели бы, чтобы он выглядел как –