将html输入值传递给knockout视图

Pass html input value to knockout view

本文关键字:knockout 视图 值传 html 输入      更新时间:2023-09-26

请帮我解决这个问题。

嵌入在CRM on Demand中,我有一个视图,需要从CRM输入字段中获取值,以便通过web服务对CRM执行搜索,并在发现重复记录时显示视图。

这里我有一些针对CRM {crm.context.ts}的库中的代码:

    /*
     * Context Helpers
     */
    declare var epmcrm: any;
    class context {

        private getParameterByName(name) {
            name = name.replace(/['[]/, "''[").replace(/[']]/, "'']");
            var regex = new RegExp("[''?&]" + name + "=([^&#]*)"),
                results = regex.exec(location.search);
            return results == null ? "" : decodeURIComponent(results[1].replace(/'+/g, " "));
        }
        config: { objects: { [key: string]: any } } = {
            objects: {
                "Homepage": {
                    name: "Homepage"
                },
                "Task": {
                    name: "Task",
                    idParam: "TaskDetailForm.Id",
                    screens: {
                        "/OnDemand/user/TaskDetail": "Detail",
                        "/OnDemand/user/TaskEdit": "Edit"
                    }
                },
                "Account": {
                    name: "Account",
                    idParam: "AccountDetailForm.Id",
                    screens: {
                        "/OnDemand/user/TaskDetail": "Detail",
                        "/OnDemand/user/TaskEdit": "Edit"
                    }
                },
                "User": {
                    name: "User",
                    idParam: "UserDetailForm.Id",
                    screens: {
                        "/OnDemand/user/UserDetail": "Detail",
                        "/OnDemand/user/UserEdit": "Edit"
                    }
                },
                "Opportunity": {
                    name: "Opportunity",
                    idParam: "OpportunityDetailForm.Id",
                    screens: {
                        "/OnDemand/user/OpportunityDetail": "Detail",
                        "/OnDemand/user/OpportunityEdit": "Edit"
                    }
                },
                "Contact": {
                    name: "Contact",
                    idParam: "ContactDetailForm.Id",
                    screens: {
                        "/OnDemand/user/ContactDetail": "Detail",
                        "/OnDemand/user/ContactEdit": "Edit",
                       // "/OnDemand/user/ContactInsert": "Create"
                    }
                }
            }
        };
        private knownPaths: { [key: string]: any } = {
            "/OnDemand/user/Homepage": this.config.objects["Homepage"],
            "/OnDemand/user/TaskDetail": this.config.objects["Task"],
            "/OnDemand/user/TaskEdit": this.config.objects["Task"],
            "/OnDemand/user/AccountDetail": this.config.objects["Account"],
            "/OnDemand/user/AccountEdit": this.config.objects["Account"],
            "/OnDemand/user/ContactDetail": this.config.objects["Contact"],
            "/OnDemand/user/ContactEdit": this.config.objects["Contact"],
           // "/OnDemand/user/ContactInsert": this.config.objects["Contact"],
            "/OnDemand/user/UserDetail": this.config.objects["User"],
            "/OnDemand/user/UserEdit": this.config.objects["User"],
            "/OnDemand/user/OpportunityEdit": this.config.objects["Opportunity"]
            //"/OnDemand/user/CustomObj2": mapping to custom objects here is important!
        };
        webServiceUrl: string = null;
        screen: string = null;
        objectType: string = null;
        objectId: string = null;
        ssoToken: string = null;
        moduleRoot: string = null;
        rowId: string = null;
        commentsAction: string = null;
        status: string = null;
        //crm parameters to built the task link;
        account: string = null;
        accountId: string = null;
        contact: string = null;
        contactId: string = null;
        quote: string = null;
        quoteId: string = null;
        order: string = null;
        orderId: string = null;
        oppty: string = null;
        opptyId: string = null;
        lead: string = null;
        leadId: string = null;
        step: string = null;
        //crm contact
        lastName: string = null;
        firstName: string = null;
        email: string = null;
        constructor() {
            // pick out the info from the url
            this.webServiceUrl = "https://" + window.location.hostname + "/Services/Integration";
            // get the SSO token from the global variable defined in the web applet
            this.ssoToken = epmcrm.ssoToken;
            // get the module root from the global variable defined in the web applet
            this.moduleRoot = epmcrm.moduleRoot;
            this.rowId = epmcrm.rowId;
            this.commentsAction = epmcrm.commentsAction;
            this.status = epmcrm.status;
            this.step = epmcrm.step;
            //crm parameters to built the task link;
            this.account = epmcrm.account;
            this.accountId = epmcrm.accountId;
            this.contact = epmcrm.contact;
            this.contactId = epmcrm.contactId;
            this.quote = epmcrm.quote;
            this.quoteId = epmcrm.quoteId;
            this.order = epmcrm.order;
            this.orderId = epmcrm.orderId;
            this.oppty = epmcrm.oppty;
            this.opptyId = epmcrm.opptyId;
            this.lead = epmcrm.lead;
            this.leadId = epmcrm.leadId;

            //crm Contact
            $("#ContactEditForm''.First'' Name").on("change", function () {
                this.firstName = (<HTMLInputElement>document.getElementById("ContactEditForm.First Name")).value;
            });
            $("#ContactEditForm''.Email'' Address").on("change", function () {
                this.email = (<HTMLInputElement>document.getElementById("ContactEditForm.Email Address")).value;
            });
            $("#ContactEditForm''.Last'' Name").on("change", function () {
                this.lastName = (<HTMLInputElement>document.getElementById("ContactEditForm.Last Name")).value;
            });
            // attempt to discover contextual information
            var pathname = window.location.pathname;
            if (this.knownPaths[pathname]) {
                var obj = this.knownPaths[pathname];
                this.objectType = obj.name;
                if (obj.idParam) {
                    this.objectId = this.getParameterByName(obj.idParam);
                }
                if (obj.screens) {
                    this.screen = obj.screens[pathname];
                }
            }

        }
    }
    export = context;
In the view models I have what should give me the results into knockout observables which should than mirror CRM field and with this results I would perform a search and return or not some results:
`contactSearch.ts`
import ko = require("knockout");
import context = require("libs/crm.context");
import contacts = require("libs/crm.contacts");
$("#BTN_TB_ContactNewForm_Save").hide();
$("#BTN_TB_ContactNewForm_Save_idx_1").hide();
//$("#ContactEditForm''.First'' Name").on("change", assignFName);
//$("#ContactEditForm''.Last'' Name").on("change", assignLName);
//function assignFName() {
//    var firstName = (<HTMLInputElement>document.getElementById("ContactEditForm.First Name")).value;
//    alert(firstName);
//}
//function assignLName() {
//    var lastName = (<HTMLInputElement>document.getElementById("ContactEditForm.Last Name")).value;
//    alert(lastName);
//}
//function assignEmail() {
//    var Email = (<HTMLInputElement>document.getElementById("ContactEditForm.Email Address")).value
//    alert(Email);
//}

//var contactViewModel = function () {
//    var self = this;
//    self.validContacts = ko.observableArray([]);
//    self.addContact = function (validContact) {
//        self.validContacts.puch(validContact);
//        $.ajax({
//            data: ko.toJSON(this),
//            contentType: 'application/json',
//            success: function (result) {
//                validContact.fName(result.
//            }
//        });
//    }
//}
class contactSearch {
    private _context: context = new context();
    private _contacts: contacts = new contacts(this._context.webServiceUrl);
    private _firstName = this._context.firstName;
    private _lastName = this._context.lastName;
    private _email = this._context.email;

    vFName = ko.observable(this._firstName);    
    vLName = ko.observable(this._lastName);     
    vEmail = ko.observable(this._email);  
    //email = ko.computed({
    //    read: () => $("#ContactEditForm''.Email'' Address").on("change", function () {            
    //    })
    //})
    ////})
    //lName = ko.observable("");
    ////email = ko.computed(function () {
    ////    assignEmail();
    //})
    isSearching: KnockoutObservable<boolean> = ko.observable(false);
    searchValue = ko.computed({
        read: () => ("[ContactEmail]~=" + "'" + "" + "'" + " AND [ContactFirstName]~=" + "'" + this.vFName() + "'" + " AND [ContactLastName]~=" + "'" + this.vLName() + "'")
    });
    contactSearchResults: KnockoutObservableArray<IContact> = ko.observableArray([]);
    doValidation() {
        $("#ContactEditForm''.Email'' Address").on("change", function () {           
        })        
    }
    doContactSearch() {
        this.isSearching(true);
        this.contactSearchResults([]);        
        this._contacts
            .find(this.searchValue(), ["Id", "ContactFirstName", "ContactLastName", "ContactEmail", "AccountId", "AccountName"])
            .done((results: IContact[]) => {
                if (results.length > 0) {
                    this.contactSearchResults(results);
                    this.isSearching(false);
                }
                else {
                    $("#BTN_TB_ContactNewForm_Save").show();
                    $("#BTN_TB_ContactNewForm_Save_idx_1").show();
                    alert("# of matching results= " + results.length);
                }
            });
    }
    bindTR(element): void {
        /*
         * Replicate the CRMOD method of hover styles
         */
        var $element = $(element);
        $element.hover(
            () => {
                $element.attr("_savedBGColor", $element.css("background-color"));
                $element.css("background-color", "#d3dde6");
            },
            () => {
                $element.css("background-color", $element.attr("_savedBGColor"));
                $element.attr("_savedBGColor", "");
            }
            );
    }
    bindLink(element): void {
        var $element = $(element);
        $element.click(
            () => {
                window["doNavigate"]('ContactDetail?ocTitle=' + encodeURIComponent(this.vLName()) + '&ContactDetailForm.Id=' + this.contactSearchResults["Id"] + '&OCTYPE=', true, this, null)
            },
            () => {
                $element.css("text-decoration", "underline");
            }
            );
    }
}
export = contactSearch;
大卫

我已经创建了可观察对象,并将它们绑定在HTML视图模型中,但我的数据源是那些HTMLInputElement,我不知道如何将值传递给可观察对象。

<p>Email <input data-bind="value: vEmail" />
    <span data-bind="text: vEmail"></span>
    <span data-bind="text: vFName"></span>
    <span data-bind="text: vLName"></span>
<p>Enter the search spec: <textarea data-bind="value: searchValue" /> 
    <button type="button" data-bind="click: validation, click: doContactSearch">Go</button></p>
<table class="list clist" cellspacing="0">
    <thead>
        <tr>
            <th class="m">
            <th class="m">
            <th>Id</th>
            <th>First Name</th>
            <th>Last Name</th>
            <th>Email</th>
            <th>Account Id</th>
            <th>Account</th>
        </tr>
    </thead>
    <tbody data-bind="visible: isSearching">
        <tr>
            <td colspan="99" style="text-align:center;">Searching, please wait...</td>
        </tr>
    </tbody>
    <tbody data-bind="foreach: contactSearchResults, afterRender: bindTR, click: bindLink">
        <tr>
            <td class="lrml">&nbsp;</td>
            <td>&nbsp;</td>
            <td data-bind="text: Id"></td>
            <td data-bind="text: ContactFirstName"></td>
            <td data-bind="text: ContactLastName"></td>
            <td data-bind="text: ContactEmail"></td>
            <td data-bind="text: AccountId"></td>
            <td data-bind="text: AccountName"></td>
        </tr>
    </tbody>
</table>

我也有这个文件,创建与CRM的依赖关系:

var epmcrm;
((epmcrm) => {
    if (!epmcrm["moduleRoot"])
        throw new Error("epmcrm global variable not configured");
    require.config({
        baseUrl: epmcrm.moduleRoot + "/scripts/app",
        paths: {
            // define the libs here
            // 1. External
            "jquery": "//cdnjs.cloudflare.com/ajax/libs/jquery/1.11.1/jquery.min",
            "jquery-ui.theme": "//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.2/jquery-ui.theme.css",// recently added
            "knockout": "//cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min",
            "text": "//cdnjs.cloudflare.com/ajax/libs/require-text/2.0.10/text",
            "json2": "//cdnjs.cloudflare.com/ajax/libs/json2/20130526/json2.min",
            "knockout.mapping": "//cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping", // added by daniel
            // 2. Internal
            "koExtensions": "../libs/knockout-extensions",
            "libs/crm.tasks": "../libs/crm.tasks",
            "libs/crm.accounts": "../libs/crm.accounts",
            "libs/crm.contacts": "../libs/crm.contacts",
            "libs/crm.users": "../libs/crm.users",
            "libs/crm.session": "../libs/crm.session",
            "libs/crm.context": "../libs/crm.context",
            "libs/crm.objects": "../libs/crm.objects",
            "libs/crm.utilities": "../libs/crm.utilities",
            "libs/crm.viewEngine": "../libs/crm.viewEngine",
            "libs/crm.viewmodelEngine": "../libs/crm.viewmodelEngine"
        },
        shim: {
            "knockout": {
                deps: ["json2"]
            }
        }
    });
    require(["knockout", "knockout.mapping", "koExtensions"],
        (ko: KnockoutStatic, komap: KnockoutMapping) => {
            ko.mapping = komap;
            ko.applyBindings({}, document.getElementById("QuoteWebAppletContainer"));
        });      
})(epmcrm || (epmcrm = {}));

我最终会拿出解决方案,因为我得到了我需要的。

修改如下:

 $("#ContactEditForm''.First'' Name").on("change", () => {
            this.firstName((<HTMLInputElement>document.getElementById("ContactEditForm.First Name")).value);
        });
        $("#ContactEditForm''.Email'' Address").on("change", () => {
            this.email((<HTMLInputElement>document.getElementById("ContactEditForm.Email Address")).value);
        });
        $("#ContactEditForm''.Last'' Name").on("change", () => {
            this.lastName((<HTMLInputElement>document.getElementById("ContactEditForm.Last Name")).value);
        });

我将这三个变量更改为可观察属性:

 lastName: KnockoutObservable<string> = ko.observable("");
    firstName: KnockoutObservable<string> = ko.observable("");
    email: KnockoutObservable<string> = ko.observable("");

这里我做了一些其他的改变:

   vFName = this._context.firstName;   
    vLName = this._context.lastName;    
    vEmail = this._context.email;
    isSearching: KnockoutObservable<boolean> = ko.observable(false);
    searchValue = ko.computed(() => {
        return ("[ContactEmail]~=" + "'" + ko.unwrap(this._context.email) + "'" + " AND [ContactFirstName]~=" + "'" + ko.unwrap(this._context.firstName) + "'" + " AND [ContactLastName]~=" + "'" + ko.unwrap(this._context.lastName) + "'")
    });