使用 Durandal 的 compose 时 JQuery 不定位 DOM 元素
Posted
技术标签:
【中文标题】使用 Durandal 的 compose 时 JQuery 不定位 DOM 元素【英文标题】:JQuery doesn't locate DOM elements when using Durandal's compose 【发布时间】:2013-09-13 02:51:11 【问题描述】:我最近使用 Knockout 和 JQuery 将我公司的项目移植到了 Durandal。直截了当地说:我需要使用两个 html 输入来初始化 JQuery UI 的日期选择器。但是,当我这样做时,JQuery 无法找到输入:
查看:
<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 - 在第一个 div 中选择用户时调用 SelectUser() 函数,然后加载第二个 div 和 users/_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
绑定更改为实际的 users/_UserDetail.html 内容,它工作得很好,但是视图很快就会变得一团糟——html文件并不小。如果有人能指出我正确的方向,我将不胜感激。谢谢!
【问题讨论】:
您应该创建一个自定义绑定处理程序并在您的视图中使用它。另请阅读有关 DOM 操作的 durandal 文档:durandaljs.com/documentation/Interacting-with-the-DOM 你在调用加载视图的代码吗?还是由框架处理? 您是指compose:
代码吗?由框架调用,但在触发SelectUser()
时会触发 - 当我从 users/_UsersList.html 中选择用户时调用此函数。
【参考方案1】:
在这种情况下,您需要一个敲除绑定处理程序。
在某些情况下,绑定处理程序可能会遇到组合生命周期问题,如果是这种情况并且您使用的是 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" />
注意:
此代码可能不起作用,但您绝对应该使用这种方法来创建此类控件并使用 Durandal 的组合生命周期。
【讨论】:
完美运行。感谢,并有一个愉快的一天! :)【参考方案2】:很确定问题出在这个:
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
函数被调用时运行。尝试将其移到任何函数之外。
【讨论】:
感谢您的回答,但是当 SelectUser 函数被触发时,_users/UserDetail.html 和两个输入被加载 - 这两个 DOM 元素直到那时才存在。 好吧,那么使用$()
或$(document).ready()
并不是正确的方法,因为视图是通过AJAX 加载的,所以ready 事件已经触发了。
你建议我应该用什么来代替 $()?
你需要弄清楚你是否可以挂钩到 durandal 的组合机制。大多数框架都会公开一个在内容被加载/添加到 DOM 时触发的事件。 那是您要设置日期选择器的地方。
好的,我会再次尝试通读他们的文档,因为我知道我需要查找什么。 :) 谢谢。以上是关于使用 Durandal 的 compose 时 JQuery 不定位 DOM 元素的主要内容,如果未能解决你的问题,请参考以下文章
你可以通过 Durandal activationData compose 绑定传递多个参数吗?