javascript - knockout : separate model from modelview

标签 javascript web knockout.js

我有一个被多个 View 模型使用的模型,并且我需要一些其他 javascript 组件来更新模型,由我的虚拟机观察到。我不知道如何做到这一点,因为在教程中,他们在 View 模型中“混合”模型。

这是我的代码:

var ConversationModel = {
    conversations: ko.observableArray(),
    open: function(userId){
        for(var i = 0; i < this.conversations.length; i++){
            if(this.conversations[i].userId == userId){
                return;
            }
        }

        var self = this;
        var obj = ko.observable({
            userId: userId
        });

        self.conversations.push(obj);

        UserManager.getUserData(userId, function(user){
            $.getJSON(Routes.messenger.getConversation, "receiver=" + userId, function(data){
                obj.receiver = user;
                obj.data = data;
            });
        });
    }
};

function ConversationDialogViewModel() {
    var self = this;

    this.conversations = ko.computed(function(){
        return ConversationModel.conversations;
    });

    console.log(this.conversations());

    this.conversations.subscribe(function(context){
        console.log(context);
    });
}

最佳答案

你可以找到一个(相当)好的例子 here如何组合:

  1. 组件
  2. 每页 ViewModel
  3. 中央服务提供商(例如,调用 API 或在不同组件之间提供状态信息)

请注意代码是 ES2015(新的 Javascript),但如果您愿意,您也可以用纯 Javascript 编写。 gulp 脚本包括对组件中的任何 html 模板进行字符串化,因此它们可以组合并作为一个文件加载,但可以作为单独的元素进行编辑。

示例组件:

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
};

和组件模板:

<div>
    <h1 data-bind="text: componentName"></h1>
    <p>Foo is currently: <span data-bind="text: foo"></span></p>
    <p>Bar is an array. It's values currently are:</p>
    <ul data-bind="foreach: bar">
        <li data-bind="text: $data"></li>
    </ul>
    <form data-bind="submit: addToBar">
        <input type="text"
               name="bar"
               placeholder="Be witty!"
               data-bind="attr: {id : componentName}, value : barValue" />
        <button type="submit">Add A Bar</button>
    </form>
    <h2>Central State</h2>
    <p>The following components are currently signed in to Central State Service Provider</p>
    <ul data-bind="foreach: CentralState.signedInComponents()">
        <li data-bind="text: $data"></li>
    </ul>
    <h2>Central Data</h2>
    <p>The following information is available from Central Data Service Provider</p>
    <table class="table table-bordered table-responsive table-hover">
        <tr>
            <th>Component Name</th><th>Second Value</th>
        </tr>
        <!-- ko foreach: CentralData.dataWeRetrieved -->
        <tr>
            <td data-bind="text: firstName"></td><td data-bind="text: secondName"></td>
        </tr>
        <!-- /ko -->
    </table>
    <h3>End of Component One!</h3>
</div>

出于您的目的,您可以忽略 Central 状态提供程序和 psuedo API,但随着您的应用变得更加复杂,您可能会发现该模型很有用。

关于javascript - knockout : separate model from modelview,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36354757/

相关文章:

javascript - 删除两个 html 元素之间的空格 : textbox and glyphicon

javascript - 禁用特定路由上特定动词的身份验证中间件

post - 网站之间的安全数据传输

knockout.js - 为什么单击事件仅针对此 KoGrid 模板中的第一个元素触发?

knockout.js - Durandal子 route 的路线未找到错误

Javascript : find regexp with capture to replace a^b by Math. pow(a, b)

javascript - Cufon 脚本在 IE9 下不起作用

javascript - knockout 给出先前选择的值

javascript - 使用 html/javascript/css 的弹出表单

javascript - 未捕获错误 : Syntax error, 无法识别的表达式:/contact - ANGULAR 2 - 路由时无法实现平滑滚动效果