KnockoutJS:与modelview分开的模型

时间:2016-04-01 11:06:01

标签: javascript web knockout.js

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

这是我的代码:

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

1 个答案:

答案 0 :(得分:0)

你可以找到一个(合理的)好例子here如何结合:

  1. 部件
  2. 每页ViewModel
  3. 中央服务提供商(例如,调用API或在不同组件之间提供状态信息)
  4. 请注意代码是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,但您可能会发现该模型非常有用,因为您的应用程序变得更加复杂。