【问题标题】:Data Bind failing for Custom HtmlControl inside ItemTemplate of ListViewListView 的 ItemTemplate 中自定义 HtmlControl 的数据绑定失败
【发布时间】:2012-08-27 16:54:25
【问题描述】:

我有一个在 ListView 上设置的 ItemTemplate:

<div class="commentTileTemplate" data-win-control="WinJS.Binding.Template">
    <div class="commentTileControl" data-win-control="WinJS.UI.HtmlControl" data-win-options="{uri: '/htmlControls/commentTile/commentTile.html'}"></div>
</div>

HtmlControl 内部的数据绑定,第一次显示 ListView 时绑定失败,在连续运行时,它工作正常。

如果我从 ListView 中删除模板,那么原始数据会按预期显示,只有在添加 HtmlControl 时它才会首先失败。

知道可能出了什么问题吗?

【问题讨论】:

    标签: javascript microsoft-metro winjs


    【解决方案1】:

    这是因为第一次加载控件时,页面是通过包中的 XHR (WinJS.xhr) 异步加载的。这意味着当第一个WinJS.Binding.process() 发生在WinJS.Binding.Template.render 函数中时,不会加载实际内容。 (例如,它的查询选择器看不到任何 data-win-bind 属性。

    第二次,因为你正在加载的片段已经在片段缓存中,它实际上是同步渲染到 DOM 中的 并且WinJS.Binding.Template.renderWinJS.Binding.processAll 看到那些data-win-bind 属性.

    这给你留下了一些选择:

    1. 在您的应用启动后立即使用WinJS.UI.Fragments.cache() 预加载片段,并且在片段完成之前不要在列表视图中设置数据
    2. 仅在您的项目已呈现时实例化HtmlControl,然后在加载时以编程方式实例化HtmlControlWinJS.Binding.process[All]() 加载的模板[1]
    3. 实际上将模板制作为您的内容,然后加载片段,处理控件。这比看起来容易,但可能需要一些时间来考虑。简而言之:加载片段,在片段上为您拥有data-win-control 的元素查询Selector,WinJS.UI.process() 它,并将模板实例返回给调用者并将其用作列表视图中的 itemTemplate

    [1] HtmlControl 构造函数接受第三个参数,这是在片段加载时调用的回调。

    【讨论】:

    • 在数据源绑定后显式调用模板的 render() 函数,似乎工作正常。 element.querySelector(".commentsListView").winControl.itemDataSource = commentsBindingList.dataSource; element.querySelector(".commentTileTemplate").winControl.render(); 这是可以接受的还是因为某些 GOTCHA 才有效,理想情况下我应该遵循上述选项之一?
    • 嗯,你不知道加载模板需要多长时间——它不是确定性的,所以这就是问题所在。你是在正确的容器元素上调用它,还是只是在没有参数的实际实例上调用它?
    • 我只是在没有参数的实际实例上调用它 -- element.querySelector(".commentTileTemplate").winControl.render(); 其中 .commentTileTemplate 是上面在原始帖子中给出的
    • 我知道这是如何工作的——这有效地执行了选项 1。这是一个实现细节——我绝对建议明确地执行选项 1,而不是这种有点骇人听闻的方式。只需调用一次 WinJS.UI.Fragments.cache("/htmlControls/cmets/foo.html") 就对您很有帮助。您甚至可以将其链接到在缓存时设置数据源的承诺。
    猜你喜欢
    相关资源
    最近更新 更多
    热门标签