简体   繁体   English

如何从视图调用我的 viewmodel 函数 - viewmodel 的子级(knockout.js)

[英]How do I call my viewmodel function from its view - child of viewmodel (knockout.js)

I have a view called agency and a viewmodel.我有一个叫做代理的视图和一个视图模型。 The viewmodel has a property also called agency where the data is contained.视图模型有一个属性,也称为代理,其中包含数据。 This data also has children but on my view my function doesn't fire when it is a child.这个数据也有孩子,但在我看来,我的函数在它还是孩子时不会触发。

<section class="view">
    <header>
        <button class="btn btn-info btn-force-refresh pull-right"
            data-bind="click: refresh">
            <i class="icon-refresh"></i>Refresh</button>

        <button class="btn btn-info"
            data-bind="click: save">
            <i class="icon-save"></i>Submit data</button>
        <br />
        <br />

        <h3 class="page-title" data-bind="text: title"></h3>
        <div class="article-counter">
            <address data-bind="text: agency().length"></address>
            <address>found</address>
        </div>
    </header>

    <table>
        <thead>
            <tr>
                <th>Agency Name</th>
                <th>Category</th>
                <th>URL</th>
                <th>Number of employees</th>
            </tr>
        </thead>
        <tbody data-bind="foreach: agency">
            <tr>
                <td>
                    <!--<input data-bind="value: agencyName" /></td>-->
                    <input data-bind="value: agencyName, event: { change: $parent.cacheForm }" />
                <td>
                    <input data-bind="value: category, event: { change: $parent.cacheForm }" /></td>
                <td>
                    <input data-bind="value: uRL, event: { change: $parent.cacheForm }" /></td>
                <td>
                    <input data-bind="value: numberOfEmployees, event: { change: $parent.cacheForm }" /></td>
            </tr>
            <tr>
                <td>Activities</td>
                <td>Declared Billings</td>
                <td>Campaigned Billings</td>
            </tr>
            <tr>
                <td>
                    <input data-bind="value: activities, event: { change: $parent.cacheForm }" /></td>
                <td>
                    <input data-bind="value: declaredBillings, event: { change: $parent.cacheForm }" /></td>
                <td>
                    <input data-bind="value: campaignBillings, event: { change: $parent.cacheForm }" /></td>
            </tr>
        </tbody>
    </table>

    <div class="article-counter">
        <div data-bind="foreach: agency">
            <address data-bind="text: offices().length"></address>
            <address>found</address>
        </div>
    </div>
    <div data-bind="foreach: agency">
        <div data-bind="foreach: offices">
            <table>
                <tr>
                    <td>
                        <h1>Offices</h1>
                    </td>
                </tr>
                <tr>
                    <td>
                        <div>
                            <table>
                                <tr>
                                    <td>Address1</td>
                                    <td>Address2</td>
                                    <td>Address3</td>
                                    <td>Address4</td>
                                </tr>
                                <tr>
                                    <td>
                                        <input data-bind="value: address1, event: { change: $parent.cacheForm }" />
                                    </td>

                                    <td>
                                        <input data-bind="value: address2, event: { change: $parent.cacheForm }" />
                                    </td>

                                    <td>
                                        <input data-bind="value: address3, event: { change: $parent.cacheForm }" />
                                    </td>

                                    <td>
                                        <input data-bind="value: address4, event: { change: $parent.cacheForm }" />
                                    </td>
                                </tr>

                                <tr>
                                    <td>Address5</td>
                                    <td>faxNumber</td>
                                    <td>postCode</td>
                                    <td>telephoneNumber</td>
                                </tr>
                                <tr>
                                    <td>
                                        <input data-bind="value: address5, event: { change: $parent.cacheForm }" />
                                    </td>
                                    <td>
                                        <input data-bind="value: faxNumber, event: { change: $parent.cacheForm }" />
                                    </td>
                                    <td>
                                        <input data-bind="value: postCode, event: { change: $parent.cacheForm }" />
                                    </td>
                                    <td>
                                        <input data-bind="value: telephoneNumber, event: { change: $parent.cacheForm }" />
                                    </td>
                                </tr>
                            </table>
                        </div>
                    </td>
                </tr>
                <tr>
                    <td>
                        <div class="article-counter">
                            <address data-bind="text: contacts().length"></address>
                            <address>found</address>
                        </div>
                    </td>
                </tr>
                <tr>
                    <td>
                        <div data-bind="foreach: contacts">
                            <table>
                                <tr>
                                    <td>Title</td>
                                    <td>First Name</td>
                                    <td>Surname</td>
                                </tr>
                                <tr>
                                    <td>
                                        <input data-bind="value: title, event: { change: $parent.cacheForm }" />
                                    </td>
                                    <td>
                                        <input data-bind="value: firstName, event: { change: $parent.cacheForm }" />
                                    </td>
                                    <td>
                                        <input data-bind="value: surName, event: { change: $parent.cacheForm }" />
                                    </td>
                                </tr>
                            </table>
                        </div>
                    </td>
                </tr>
            </table>
        </div>
    </div>
</section>

When I change these values for example my function fires, it is the parent.当我更改这些值时,例如我的函数触发时,它是父级。

<tbody data-bind="foreach: agency">
                <tr>
                    <td>
                        <!--<input data-bind="value: agencyName" /></td>-->
                        <input data-bind="value: agencyName, event: { change: $parent.cacheForm }" />
                    <td>
                        <input data-bind="value: category, event: { change: $parent.cacheForm }" /></td>
                    <td>
                        <input data-bind="value: uRL, event: { change: $parent.cacheForm }" /></td>
                    <td>
                        <input data-bind="value: numberOfEmployees, event: { change: $parent.cacheForm }" /></td>
                </tr>

When I loop inside each agency and then each office like this:当我在每个机构然后每个办公室都这样循环时:

<div data-bind="foreach: agency">
        <div data-bind="foreach: offices">
            <table>
                <tr>
                    <td>
                        <h1>Offices</h1>
                    </td>
                </tr>
                <tr>
                    <td>
                        <div>
                            <table>
                                <tr>
                                    <td>Address1</td>
                                    <td>Address2</td>
                                    <td>Address3</td>
                                    <td>Address4</td>
                                </tr>
                                <tr>
                                    <td>
                                        <input data-bind="value: address1, event: { change: $parent.cacheForm }" />
                                    </td>

                                    <td>
                                        <input data-bind="value: address2, event: { change: $parent.cacheForm }" />
                                    </td>

                                    <td>
                                        <input data-bind="value: address3, event: { change: $parent.cacheForm }" />
                                    </td>

                                    <td>
                                        <input data-bind="value: address4, event: { change: $parent.cacheForm }" />
                                    </td>
                                </tr>

This function won't fire这个功能不会触发

<input data-bind="value: address1, event: { change: $parent.cacheForm }" />

I don't know the correct syntax to fire this function from agency.office.我不知道从 agent.office 触发这个函数的正确语法。

This is my entire viewmodel这是我的整个视图模型

define(['services/datacontext'], function (dataContext) {
    var initialized = false;
    var agency;

    if (localStorage.Agency && localStorage.Offices && localStorage.Contacts) {
        var objAgency = new Object(ko.mapping.fromJSON(localStorage.getItem('Agency')));
        var objOffices = new Object(ko.mapping.fromJSON(localStorage.getItem('Offices')));
        var objContacts = new Object(ko.mapping.fromJSON(localStorage.getItem('Contacts')));

        objAgency.offices = objOffices;
        objAgency.offices._latestValue[0].contacts = objContacts;


        agency = ko.observableArray([ko.mapping.fromJS(objAgency)]);
        ko.applyBindings(agency);

        initialized = true;

    }
    else {
        agency = ko.observableArray([]);
    }


    var save = function (agency, myStoredValue) {
        // Clear Cache because user submitted the form. We don't have to hold onto data anymore.
        //amplify.store("Agency", null);
        return dataContext.saveChanges(agency);
    };

    var vm = { // This is my view model, my functions are bound to it. 
        //These are wired up to my agency view
        activate: activate,
        agency: agency,
        title: 'agency',
        refresh: refresh, // call refresh function which calls get Agencies
        save: save,
        cacheForm: cacheForm
    };
    return vm;

    function activate() {

        vm.agency;

        if (initialized) {
            return;
        }

        initialized = false;

        return refresh();

    }

    function refresh() {
        return dataContext.getAgency(agency);
    }


    function cacheForm(agency) {
        // GET my object from agency vm
        var agency = ko.toJS(agency);

        var s = YUI().use("json-stringify", function (Y) {

            var jsonStrAgency = Y.JSON.stringify(agency, ["activities", "agencyName", "agencyID", "campaignBillings", "category", "declaredBillings", "immediateParent", "numberOfEmployees", "ultimateParent", "uRL"]); // Use an array of acceptable object key names as a whitelist.
            var jsonStrOffices, jsonStrContacts;

            for (i in agency.offices) {
                jsonStrOffices = Y.JSON.stringify(agency.offices, ["address1", "address2", "address3", "address4", "address5", "agencyID", "faxNumber", "officeID", "postCode", "telephoneNumber"]);

                for (ii in agency.offices[i].contacts) {
                    jsonStrContacts = Y.JSON.stringify(agency.offices[i].contacts, ["agencyID", "emailAddress", "firstName", "jobName", "officeID", "personID", "surName", "title"]);
                }
            }

            localStorage.setItem('Agency', jsonStrAgency);
            localStorage.setItem('Offices', jsonStrOffices);
            localStorage.setItem('Contacts', jsonStrContacts);
        });
    }
});

If my question doesn't make sense I can try to explain it better.如果我的问题没有意义,我可以尝试更好地解释它。 I am new to using knockout so I don't know how to best explain it.我是使用淘汰赛的新手,所以我不知道如何最好地解释它。

If you want to go all the way up to your root view model, then you can use $root instead of $parent .如果你想一直到你的根视图模型,那么你可以使用$root而不是$parent If you want to walk up the scopes, then you can use the $parents array.如果你想走上范围,那么你可以使用$parents数组。

If I understand your structure it looks like either $root.cacheForm or $parents[1].cacheForm would work.如果我理解你的结构,它看起来像$root.cacheForm$parents[1].cacheForm都可以。 Note that the item passed would be the "office".请注意,通过的项目将是“办公室”。

You can alternatively handle something like this purely on the view model side by using a computed observable to grab dependencies on all of the things that you care about.您也可以通过使用计算的 observable 来获取对您关心的所有事物的依赖关系,从而纯粹在视图模型方面处理类似的事情。 Something like this: http://www.knockmeout.net/2011/05/creating-smart-dirty-flag-in-knockoutjs.html像这样: http : //www.knockmeout.net/2011/05/creating-smart-dirty-flag-in-knockoutjs.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM