2013-09-09 2 views
1

Недавно я перенес проект моей компании в Durandal с помощью Knockout и JQuery. Прямо к проблеме: мне нужно инициализировать датпикер JQuery UI, используя два входа HTML. JQuery, однако, не в состоянии найти входы, когда я делаю это:JQuery не находит элементы DOM при использовании компоновки Durandal

вид:

<div data-bind="if: !CurrentUser()"> 
    <h1 data-bind="html: DisplayName"></h1> 

    <div data-bind="compose: 'users/_UsersList.html'"></div> 
</div> 

<div data-bind="with: CurrentUser(), visible: CurrentUser()"> 
    <h1>User detail</h1> 

    <div data-bind="compose: 'users/_UserDetail.html'"></div> 
</div> 

ViewModel - SelectUser() вызывается при выборе пользователем в первом DIV, затем второй DIV, а также пользователей/_UserDetail.html загружен:

users.SelectUser = function (user) { 
    users.CurrentUser(user); 

    /* ... */ 

    $(function() { 
     $("#datepickerFrom").datetimepicker({ 
      dateFormat: "d. m. yy", 
      timeFormat: "HH:mm:ss", 
      defaultDate: null 
     }); 

     $("#datepickerTo").datetimepicker({ 
      dateFormat: "d. m. yy", 
      timeFormat: "HH:mm:ss" 
     }); 
    }); 
} 

важной частью _UserDetail.html

<div class="control-group"> 
    <label class="control-label">Active from</label> 
    <div class="controls"> 
     <input type="text" data-bind="value: ActiveFrom" id="datepickerFrom" /> 
    </div> 
</div> 
<div class="control-group"> 
    <label class="control-label">Active to</label> 
    <div class="controls"> 
     <input type="text" data-bind="value: ActiveTo" id="datepickerTo" /> 
    </div> 
</div> 

Затем два входа HTML входят как неопределенные. Если я изменю div с привязкой compose к фактическому содержимому/_UserDetail.html, он работает нормально, но тогда представление быстро становится беспорядок - html-файл не совсем мал. Если бы кто-то мог указать мне в правильном направлении, я был бы благодарен. Благодаря!

+0

Вы должны создать собственный обработчик привязки и использовать его в своем представлении. Также прочитайте durandal doc о манипуляциях с DOM: http://durandaljs.com/documentation/Interacting-with-the-DOM/ – nemesv

+0

Вызываете ли вы код, загружающий представление? или это обрабатывается каркасом? – rossipedia

+0

Вы имеете в виду 'compose:' code? Это вызвано фреймворком, но он срабатывает при срабатывании 'SelectUser()' - я вызываю эту функцию, когда я выбираю пользователя из пользователей/_UsersList.html. –

ответ

4

В этом сценарии вам нужен обработчик привязки нокаута.

В некоторых сценариях обработчики привязки могут иметь проблемы с жизненным циклом композиции, если это случай, и вы используете Durandal 2, вы можете использовать метод composition.addBindingHandler. В противном случае просто используйте ko.bindingHandlers.

Вам необходимо будет создать привязки в shell.js или main.js, чтобы они были доступны во всех приложениях. Используйте следующий код:

var composition = require('durandal/composition'); 
composition.addBindingHandler('datetimepicker', { 
      init: function (element, valueAccessor) { 
       var activeTo = valueAccessor(); //What do you want to do with this value? 
       $(element).datetimepicker({ 
        dateFormat: "d. m. yy", 
        timeFormat: "HH:mm:ss", 
        defaultDate: null //Maybe use activeTo here? 
        }); 
      } 
     }); 

И в вашем пользовательском интерфейсе:

<input type="text" data-bind="datetimepicker: ActiveTo" id="datepickerTo" /> 

Примечание:

Этот код может не работать, но вы должны обязательно использовать этот подход для создания такого рода контроля и использования жизненного цикла композиции Дюрандаля.

+0

Спасибо! Я попробую это и дам вам знать, если это сработает. :) –

+0

Работает безупречно. Спасибо, и хорошего дня! :) –

+0

Coooool! Вы тоже человек! – margabit

1

Довольно уверены, что проблема с этим:

users.SelectUser = function (user) { 
    servers.CurrentUser(user); 

    /* ... */ 

    $(function() { 
     $("#datepickerFrom").datetimepicker({ 
      dateFormat: "d. m. yy", 
      timeFormat: "HH:mm:ss", 
      defaultDate: null 
     }); 

     $("#datepickerTo").datetimepicker({ 
      dateFormat: "d. m. yy", 
      timeFormat: "HH:mm:ss" 
     }); 
    }); 
} 

У вас есть JQuery код DatePicker инициализации внутри функции. Это означает, что он будет работать только при вызове функции SelectUser. Попробуйте переместить это вне любых функций.

+0

Спасибо за ваш ответ, но когда функция SelectUser запущена, то _users/UserDetail.html и два входа загружаются - два элемента DOM не существуют до тех пор. –

+0

Ну, тогда используйте '$()' или '$ (document).ready() 'на самом деле не самый правильный путь, поскольку, поскольку представление загружается через AJAX, готовое событие уже запущено. – rossipedia

+0

Что вы предлагаете использовать вместо $()? –