动态淘汰模板模式潜在缺陷

Dynamic Knockout Template Pattern Potential Pitfalls

本文关键字:缺陷 模式 淘汰 动态      更新时间:2024-06-22

我正在使用require和knockout创建一个类似小部件的仪表板,我想知道是否有人能看到我使用的方法的任何潜在缺点。

我有一个带有模板和一个自定义绑定(仪表板)的布局:

注意:可以将仪表板绑定视为模板绑定的克隆,当从dashboardItems可观察集合添加/删除项目时,它将为布局相关功能提供帮助。

<!-- snip -->
    <div>
        <ul data-bind="dashboard: { templateName: 'dashboard-item', items: dashboardItems' }"></ul>
    </div>
    <script id="dashboard-item" type="text/html">
        <li>
            <div data-bind="component: { name: componentName, params: $data }"></div>
        </li>
    </script>
    <script id="dashboard-container" type="text/html">    
        <div class="dashboard-container">
            <!-- other ko templates common to all widgets -->    
            <!-- ko if: configMode -->
                <!-- this section is specific to each widget -->    
                <!-- ko template: configTemplateId --><!-- /ko -->
            <!-- /ko -->
            <!-- ko ifnot: configMode -->
                <!-- this section is specific to each widget -->    
                <!-- ko template: contentTemplateId --><!-- /ko -->
            <!-- /ko -->
            <!-- other ko templates common to all widgets -->    
        </div>
    </script>
<!-- /snip -->

我有一个通过require加载的组件:

<script data-bind="attr: { id: configTemplateId }" type="text/html">
    <!-- layout/content specific to this widget/section -->
</script>
<script data-bind="attr: { id: contentTemplateId }" type="text/html">
    <!-- layout/content specific to this widget/section -->
</script>
<div data-bind="template: 'widget-container'"></div>

所有组件视图模型都继承自一个基类:

<!-- snip -->
    function componentBase(config) {
        var self = this;
        self.configTemplateId = ko.observable("config_" + config.uid);
        self.contentTemplateId = ko.observable("content_" + config.uid);
    };
<!-- /snip -->

这就是发生的事情:

  1. 加载包含"仪表板容器"模板的主页面
  2. 一个组件视图模型被添加到可观察的dashboardItems中
  3. 自定义组件加载程序使用require加载并绑定到组件的视图
  4. 组件视图模型的configTemplateId和contentTemplateId绑定到其视图中脚本标记的id属性
  5. KO从组件模板加载"仪表板组件"模板,然后在视图模型上找到配置和内容模板ID,并将它们加载到"仪表板部件"模板的相应区域中

我这样做的原因是因为所有的小部件共享相同的基本模型,所以我想在一个位置配置一些常见的方面/模板(加载模板、配置模板等),这些方面/模板在"小部件容器"中,但为了简洁/干净,从本文中删除了。

关键是,我不想记住在每个小部件模板中包含什么以及在哪里添加这些内容,然后如果需要更改,就必须在每个小组件中进行更改。

毕竟,问题很简单:以这种方式使用ko模板绑定时,有人能看到任何潜在问题吗?或者有人能想出更好的方法吗?也许有一种方法可以为临时绑定提供对占位符的引用,并将其注入其中?

提前感谢!

Mike

当您有很多组件需要访问共享的中央资源时,例如数据api或中央应用程序状态,那么提前进行一些规划是值得的。

我有自己的格式-与其说是种子程序,不如说是概念证明-它包括使用require的单独模块、同一页面上的多个组件、中央资源和组件之间的交互,还包括对babel-ES2015(新Javascript)的支持,并且被吞噬了。

https://github.com/brianlmerritt/knockout-babel-browserify-gulp

示例组件:

const ko = require('knockout')
    , CentralData = require('../../service-providers/central-data')
    , CentralState = require('../../service-providers/central-state')
    , template = require('./template.html');
const viewModel = function (data) {
    //Make service providers accessible to data-bind and templates
    this.CentralData = CentralData;
    this.CentralState = CentralState;
    this.componentName = 'Component One';
    this.foo = ko.observable(`${this.componentName} Foo`);
    this.bar = ko.observableArray(this.componentName.split(' '));
    this.barValue = ko.observable("");
    this.bar.push('bar');
    this.addToBar = (stuffForBar) => {
        if(this.barValue().length >= 1) {
            this.bar.push(this.barValue());
            CentralData.pushMoreData({firstName: this.componentName,secondName:this.barValue()});
        }
    };
    this.CentralState.signIn(this.componentName);
    if (CentralData.dataWeRetrieved().length < 10) {
        var dataToPush = {firstName : this.componentName, secondName : 'Foo-Bar'};
        CentralData.pushMoreData(dataToPush);
    }
};
console.info('Component One Running');
module.exports = {
    name: 'component-one',
    viewModel: viewModel,
    template: template
};

以及一个示例服务提供商

const ko = require('knockout');
const CentralState = {
    signIn : componentName => signIn(componentName),
    signedInComponents : ko.observableArray([]),
};
const signIn = (componentName) => {
    if (CentralState.signedInComponents().indexOf(componentName) < 0) {
        CentralState.signedInComponents.push(componentName);
    }
};
console.info('Central State Running');
module.exports = CentralState;

您可以添加模型来管理特定的数据类型,并且您可能希望将配置器作为中心服务提供商。