Sencha ExtJS MVC - 在 运行 时间指定的数据源

Sencha ExtJS MVC - data source specified at run time

我想按照这些思路编写一个概念验证应用程序:

查看

- a URL text input field at top with Go button
- a big DIV underneath consisting of the rest of the view

控制器

- upon Go pressed, validate the URL text
- set up the URL to the data source
- read data from the data source
- create a nested DIV element for each data, apply CSS rules
- add the element to the big DIV

型号

- define the fields
- define the default ordering

CSS

- define the styles

首先,我上面写的东西是否在 ExtJS 中工作,或者我是否会与框架作斗争?特别是,插入普通 HTML 作为元素节点。

其次,有人知道 GPL 下的现有项目可以作为起点吗?到目前为止,我所看到的都是带有硬编码 URL 并设置为自动加载的华而不实的示例。

您所写的内容没有任何可怕或令人不安的内容。

虽然没有太多宣传,ExtJS 处理自定义 HTML 和 CSS 相当好。您可以使用 html or tpl 配置选项设置一些。后者由 XTemplates 提供支持,因此您可以执行循环等。当使用这些选项 and/or 自定义 CSS 时,Ext 将围绕渲染结果计算其布局,自动考虑您的自定义样式。现在,实际上,框架需要做大量工作,它并不总是按预期工作,而且在某些浏览器上根本无法工作(当然,比如不太旧的 IE)。您应该注意的一个大陷阱是,您应该始终为 CSS 使用 px 中的整数值,因为如果维度解析为 px 中的小数值,Ext 将阻塞那。

也就是说,由于您显然要使用模型来支持数据,因此您可能应该使用 dataview。这是一个允许您在常规 Ext 存储上使用自定义 HTML 的组件。然后它为项目选择、分页等提供好东西。它是其他高级数据视图的基础 class,例如 Ext 网格。

关于 URLs,您不必在模型的代理(或其他地方)中对它们进行硬编码。您可以将 URL 传递给现有商店的 load method (as documented here).

最后,我不知道现有的项目,但您的 POC 非常简单,所以这里有一个 fiddle 可以帮助您入门。该代码不是 100% 干净的,特别是在单个文件中定义所有内容,因此缺少所有 requires... 但它说明了您所询问的大部分要点。阅读有关用于了解如何超越这一点的组件/方法的文档。

这是 fiddle 的代码:

Ext.define('Foo.model.Item', {
    extend: 'Ext.data.Model',
    fields: ['name']
});

Ext.define('Foo.view.MainController', {
    extend: 'Ext.app.ViewController',

    alias: 'controller.main',

    onGo: function() {
        var view = this.getView(),
            url = view.down('textfield').getValue(),
            dataview = view.down('dataview'),
            store = dataview.getStore();
        if (this.isValidUrl(url)) {
            store.load({url: url});
        } else {
            Ext.Msg.alert(
                "Invalid URL",
                "This URL cannot be loaded here: " + url
            );
        }
    },

    // private
    isValidUrl: function(url) {
        return ['data1.json', 'data2.json'].indexOf(url) !== -1;
    }
});

Ext.define('Foo.view.Main', {
    extend: 'Ext.Panel',

    xtype: 'main',
    controller: 'main',

    layout: {
        type: 'vbox',
        align: 'stretch'
    },

    items: [{
        xtype: 'container',
        layout: 'hbox',
        margin: 3,
        defaults: {
            margin: 3
        },
        items: [{
            flex: 1,
            xtype: 'textfield',
            emptyText: "Valid inputs are 'data1.json' or 'data2.json'",
            listeners: {
                specialkey: function(field, e) {
                    if (e.getKey() === e.ENTER) {
                        // custom event, for the fun of it
                        field.fireEvent('enterkey', field, e);
                    }
                },
                // the custom can be bound to controller in "modern ext" way
                enterkey: 'onGo'
            }
        },{
            xtype: 'button',
            text: "Go",
            handler: 'onGo'
        }]
    },{
        flex: 1,
        xtype: 'dataview',
        margin: '0 6 6 6',
        cls: 'my-dataview', // for CSS styling
        store: {
            model: 'Foo.model.Item',
            autoLoad: false
            // default proxy is ajax and default reader is json,
            // which is cool for us
        },
        tpl: '<tpl for=".">' + '<div class="item">{name}</div>' + '</tpl>',
        itemSelector: '.item'
    }]
});

Ext.application({
    name : 'Foo',
    mainView: 'Foo.view.Main'
});

部分CSS数据视图:

.my-dataview .item {
    padding: 1em;
    border: 1px solid cyan;
    color: magenta;
    float: left;
    margin: 6px;
    width: 100px;
}

还有一个示例 JSON 响应(这是最低限度的功能...阅读代理和 reader 以进一步了解):

[{
    name: 'Foo'
},{
    name: 'Bar'
},{
    name: 'Baz'
}]