带有复杂下拉菜单的 dijit.form.ComboBox

发布于 2024-10-18 23:45:38 字数 2152 浏览 0 评论 0原文

我想创建一个更有趣的博客自动完成小部件;将返回一个下拉菜单,其中包含:(a) 标题、(b) 关键字、(d) 日期。例如:

|======================
| inte|
|======================
| Interesting Title
| Tags: title, bar
| Date: Jun, 12 2010
|----------------------
| Interner Guide 
| Tags: guide
| Date: Aug, 12 2010
|----------------------
|          ...
|======================

我。第一个选项

实现此目的的一种方法是重写 _ComboBoxMenu 的 _createOption,如下所示:

dojo.declare("SearchBox", dijit.form.ComboBox, {
    postMixInProperties: function() {
        this._popupWidget = new SearchBoxMenu();
        this.inherited(arguments);
    }
});

dojo.declare("SearchBoxMenu", dijit.form._ComboBoxMenu, {
    _createOption: function(item, labelFunc) {
        var menuitem = dojo.doc.createElement("li");
        menuitem.innerHTML = [
            "<ul>",
                "<li>", store.getValue(item, "title"), "</li>",
                "<li>Tags: ", store.getValue(item, "tags"), "</li>",
                "<li>Date: ", store.getValue(item, "date"), "</li>"
            "</ul>"
        ].join("")
        return menuitem;
    }
});

但我 (a) 重写私有类,然后 (b) 它是私有方法,因此如果这些方法签名发生更改dojo 1.6 中的课程——我会遇到麻烦。这使得这种方式有点不可取。

二.第二个选项

如果私有 API 签名发生更改,第二种方法不会中断,但会将数据与表示混合在一起:

var myStore = new dojo.data.ItemFileReadStore({
    data: {
        identifier: "title",
        items:  [
            {title: "Interesting Title",
             tags: "title, bar",
             date: "Jun, 12 2010",
             label: "<ul><li>Interesting Title</li>"
                 + "<li>Tags: title, bar</li>"
                 + "<li>Date: Jun, 12 2010</li></ul>"}
        ]
    }
});

var box = new dijit.form.ComboBox({
    store: myStore,
    searchAttr: "title",
    labelAttr: "label",
    labelType: "html"
}, "ipt1"),

labelAttr 告诉 ComboBox 查看数据存储的 items[].label 并在下拉菜单中使用它。 “labelType”告诉 _ComboBoxMenu 将其包含为 HTML,而不是简单的字符串。正如我上面提到的,这种方法的一个缺点是它将数据与表示混合在一起。

问题:因此,我有两个选择,但都不是完美的。有更好的办法吗?如果没有——您推荐哪一个?

I'd like to create a more interesting blog autocomplete widget; one that will return a drop-down menu that will contain: (a) title, (b) keywords, (d) date. E.g.:

|======================
| inte|
|======================
| Interesting Title
| Tags: title, bar
| Date: Jun, 12 2010
|----------------------
| Interner Guide 
| Tags: guide
| Date: Aug, 12 2010
|----------------------
|          ...
|======================

I. First Option

One way of achieving this is by overriding the _createOption of the _ComboBoxMenu like this:

dojo.declare("SearchBox", dijit.form.ComboBox, {
    postMixInProperties: function() {
        this._popupWidget = new SearchBoxMenu();
        this.inherited(arguments);
    }
});

dojo.declare("SearchBoxMenu", dijit.form._ComboBoxMenu, {
    _createOption: function(item, labelFunc) {
        var menuitem = dojo.doc.createElement("li");
        menuitem.innerHTML = [
            "<ul>",
                "<li>", store.getValue(item, "title"), "</li>",
                "<li>Tags: ", store.getValue(item, "tags"), "</li>",
                "<li>Date: ", store.getValue(item, "date"), "</li>"
            "</ul>"
        ].join("")
        return menuitem;
    }
});

But I'm (a) overriding a private class, then (b) it's private method, so if the method signature changes for these classes in dojo 1.6 -- I'll be in trouble. This makes this way a bit undesirable.

II. Second Option

The second way will not break if the private API signature changes, but does mix data with presentation:

var myStore = new dojo.data.ItemFileReadStore({
    data: {
        identifier: "title",
        items:  [
            {title: "Interesting Title",
             tags: "title, bar",
             date: "Jun, 12 2010",
             label: "<ul><li>Interesting Title</li>"
                 + "<li>Tags: title, bar</li>"
                 + "<li>Date: Jun, 12 2010</li></ul>"}
        ]
    }
});

var box = new dijit.form.ComboBox({
    store: myStore,
    searchAttr: "title",
    labelAttr: "label",
    labelType: "html"
}, "ipt1"),

The labelAttr tells the ComboBox to look at the dataStore's items[].label and use that in the drop-down menu. The "labelType" tells the _ComboBoxMenu to include it as HTML instead of as a simple string. As I've mentioned above, one disadvantage of this method is that it mixes data with presentation.

Question: Thus, I have two options, but neither is perfect. Is there a better way? If not -- which one do you recommend?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

伤痕我心 2024-10-25 23:45:38

答案在“autoComplete”测试页面上的富文本测试中进行了描述: http://archive.dojotoolkit.org/nightly/dojotoolkit/dijit/tests/form/_autoComplete.html#richtextest

唯一让我感觉好一点的是我之前尝试过这个解决方案,但它不适用于 dojo 1.5。它确实适用于夜间,并且希望适用于所有后续的稳定版本。它是选项 2 和标签视图函数的组合:

var myStore = new dojo.data.ItemFileReadStore({
  data: {
        identifier: "title",
        items:  [
            {title: "Interesting Title",
             tags: "title, bar",
             date: "Jun, 12 2010"}
        ]
    }
});

var box = new dijit.form.ComboBox({
    autoComplete: false,
    selectOnClick: true,
    store: myStore,
    searchAttr: "title",
    labelType: "html",
    labelFunc: function(item, store) {
        return [
            "<ul>",
                "<li>", store.getValue(item, "title"), "</li>",
                "<li>Tags:", store.getValue(item, "tags"), "</li>",
                "<li>Date:", store.getValue(item, "date"), "</li>",
            "</ul>"
        ].join("")
    }
}, "ipt1");

The answer was described in the Rich Text Test on the "autoComplete" test page: http://archive.dojotoolkit.org/nightly/dojotoolkit/dijit/tests/form/_autoComplete.html#richtextest.

The only thing that makes me feel a bit better is that I've tried this solution before, and it didn't work with dojo 1.5. It does work on the nightlies and, hopefully, with all subsequent stable builds. It's a combination of option 2 and a label-view function:

var myStore = new dojo.data.ItemFileReadStore({
  data: {
        identifier: "title",
        items:  [
            {title: "Interesting Title",
             tags: "title, bar",
             date: "Jun, 12 2010"}
        ]
    }
});

var box = new dijit.form.ComboBox({
    autoComplete: false,
    selectOnClick: true,
    store: myStore,
    searchAttr: "title",
    labelType: "html",
    labelFunc: function(item, store) {
        return [
            "<ul>",
                "<li>", store.getValue(item, "title"), "</li>",
                "<li>Tags:", store.getValue(item, "tags"), "</li>",
                "<li>Date:", store.getValue(item, "date"), "</li>",
            "</ul>"
        ].join("")
    }
}, "ipt1");
夜夜流光相皎洁 2024-10-25 23:45:38

我认为没有更好的方法。

就我个人而言,我会选择选项 1,并记录您正在使用的所有私有 API,并应在升级时进行检查。更好的是,提供一个用于挂钩您自己的弹出窗口小部件的补丁并提交它,确保下一个版本具有您想要在其中看到的更改:)

I don't think there is a better way.

Personally I'd go for option 1 and keep a record of all the private APIs you're using and should check for on upgrade. Better yet, provide a patch for hooking in your own popup widget and submit it, making sure the next version has the change you want to see in it :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文