Я искал и нашел несколько похожих вопросов для себя, но ни один из них не соответствует тому, что я пытаюсь сделать (или, по крайней мере, решения для меня не работали). Я действительно новичок в 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]
• This is a sample selectable area. This will be highlighted<br />
when someone mouses over it.
<br />[/selectable]
Длинные дивы были заменены тегами [выбираемых], чтобы сделать его проще для кого-то с основными HTML навыков для построения образца документа.
В конечном счете, цель состоит в том, чтобы дать человеку, создавшему документ легкий тег для работы, вместо того, чтобы пытаться вставить длинный тег и отслеживать его индивидуальный идентификатор. Я хочу, чтобы события мыши были привязаны к viewmodel, так как это все та же деятельность (и точки для всех документов будут подсчитываться вместе для окончательного результата). С точки зрения пользователя, когда они курсируют над выбираемым текстом, он должен просто менять цвет (простой jQuery). Если они нажмут на него, он проверяет, выбрана ли у них подходящая категория (у меня уже есть эта работа). Моя текущая проблема заключается в замене текста и возможности привязки событий к функциям представления.
Это работало отлично для меня. Я закончил использование $ root с событием привязкой данных во внешнем HTML, и он работал как шарм. Спасибо тебе за помощь, Эван! –
Кажется, у меня все еще есть проблемы с этим. После представления нового решения боссу ему не понравился длинный тег div, который требуется для того, чтобы он включал привязки событий во внешний html-файл. Это связано с тем, что не-dev, вероятно, создаст эти внешние документы. В настоящее время я получил его html-файл с вызовом AJAX, а затем заменил простой пользовательский тег «[selectable]» длинным тегом div и сохранил его в наблюдаемом, но я все еще не уверен, как его включить привязки к текущему виду. Любая идея, где я могу идти отсюда? Я в тупике. –
можете ли вы разместить какой-либо код, пожалуйста, а также то, что вы хотели бы, чтобы он выглядел как –