KnockoutJS:组件绑定,使用对象作为数据类型

时间:2015-07-27 14:23:06

标签: components mediator knockout-3.0

我是Knockout JS的新手,我发现这个库非常强大,但有时很难理解。文档很简单,但它总是(太)小代码片段,所以除非你的编码风格和范围很大,否则很难有大局。哲学范式与KO开发人员相同。

我来自角度世界,我习惯拥有一个数组,其中每个项目都是具有属性(id,name等)的对象。当我单击一个按钮时,我将此对象“发送”到一个新组件,该组件将以表单形式呈现它。

我确信我错过了一些明显的东西,但我不明白如何让事情有效,即使是像ko.mapping和ko.postbox这样的插件。

有没有人可以帮我找到解决方案?在上面的工作代码中,我在javascript区域发布了我的3个非常具体的问题。

编辑:我回答他们,但我不知道这是不是最好的做法

var
    // User class to give to each property the observable capacity
    User = function (rawData) {
        var self = this,
            data = rawData || {};

        self.id = ko.observable(data.id);
        self.name = ko.observable(data.name);
    },

    // List component. initially in a separate file
    // (small modifs so all can be in the same file for this demo)
    cmplist = {
        viewModel: function () {
            var self = this;
            self.users = ko.observableArray([
                new User({id: 1, name: 'John'}),
                new User({id: 2, name: 'Jack'}),
                new User({id: 3, name: 'Smith'})
            ]);

            // #ANSWER 1: initialize postbox event
            self.user = ko.observable(new User()).publishOn('userEdit');

            self.showEdit = function (user) {
                // #QUESTION 1: how do I send this object to the
                //              users-form component. ko.postbox?
                // #ANSWER 1: change the observable
                self.user(user);
                console.log('show', user);
            };
        },
        template: ''
            + '<ul data-bind="foreach: users">'
            + '<li>'
            + '<button data-bind="click: $parent.showEdit">Edit</button>'
            + '&nbsp;<span data-bind="text: name"></span>'
            + '</li>'
            + '</ul>'
    },

    // Form component, initially in a separate file
    // (small modifs so all can be in the same file for this demo)
    cmpform = {
        viewModel: function () {
            var self = this;
            // #QUESTION 2: how do I recept the object sent by the
            //              list?
            // #ANSWER 2: make the observable subscribe to event
            self.user = ko.observable(new User()).subscribeTo('userEdit');

            self.save = function () {
                // #QUESTION 3: how do I notify the users-list cmp
                //              that object has changed? ko.postbox?
                window.alert('save ' + ko.toJSON(self.user()));
                console.log('save');
            };
        },
        // #ANSWER 2: call user() with parenthesis to access properties
        template: ''
            + '<form>'
            + '<p>Edit user <span data-bind="text: user().name"></span> '
            + 'with id <span data-bind="text: user().id"></span></p>'
            + '<input data-bind="textInput: user().name" />'
            + '<button data-bind="click: save">Save</button>'
            + '</form>'
    };

// KO bootstrap, initially in a 3rd file
// (small modifs so all can be in the same file for this demo)
ko.components.register('users-list', cmplist);
ko.components.register('users-form', cmpform);
ko.applyBindings({});
ul { 
  border: 1px solid blue; 
  list-style: none; 
  float: left;
}

li { 
  border: 1px solid green; 
}

form { 
  border: 1px solid red;
  float: right;
  margin-top: 20px;
}

ul, li, form { 
  padding: 5px; 
}
<html>
    <head>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout-postbox/0.5.2/knockout-postbox.min.js"></script>
    </head>
    <body>

        <users-list></users-list>
      
        <users-form></users-form>

    </body>
</html>

0 个答案:

没有答案