1

我正在开发一个 SharePoint 场解决方案,其中我有一个包含我的用户控件的控件模板。我正在使用 Knockout 模型来捕获屏幕上的所有信息。最初,当单击新项目时,我第一次调用我的模型以初始化用户控件并使用 ScriptManager RegisterStartupScript 将控件绑定到屏幕(所有值最初都是空的,日期除外)。现在,当用户填写值时,我的模型会捕获所有更改,我有一个函数可以获取模型,将其转换为 XMl 并将其保存在隐藏的文本框中。但我无法从后面的控制模板代码中获取该 java 脚本函数。我可以通过按钮输入使其工作,但我需要它在没有任何按钮的情况下工作。我再次尝试使用 RegisterScripts,但没有 t 工作,因为该页面从未重新加载。如何在不使用按钮的情况下再次调用模型?谢谢!!

这是我的代码片段:

JavaScript

 $(document).ready(function () {

    MyMasterviewModel = {
    myViewModel: new viewmodel()
    }
    ko.applyBindings(MyMasterviewModel);

   })


 var myViewModel;

 var viewmodel = function () {
 var self = this;
 self.InitializeEntity = function () {
 var initialURL = "~/_layouts/EinvoiceMVCService.asmx/InitializeModel";
        $.ajax({
            type: "Post",
            url: initialURL,
            contentType: "application/json; charset=utf-8",
            data: {},
            dataType: "json",
            success: function initializesuccess(msg) {
             //I get the data here
            },
            error: oninitialFail

        });
    }
    self.GetXmlFromModel = function () {
        var getxmlurl = "~/_layouts/EinvoiceMVCService.asmx/GetXml";
        var mod = ko.mapping.toJS(MyMasterviewModel.myViewModel.invoice());
        var DTO = { 'p_invoice': mod }
        $.ajax({
            type: "Post",
            url: getxmlurl,
            contentType: "application/json; charset=utf-8",
            data: JSON.stringify(DTO),
            dataType: "xml",
            success: function XMLsuccess(msg) {

              //I get XML string and store it in a text box
              var xmlstring = msg.xml;
              document.getElementById("<%= txtxml.ClientID %>").value = xmlstring;
            },
            error: oninitialFail
        })

    } 

HTML

 <tr>
 <td align="right">
   Invoice Amount:
 </td>
 <td align="left">
  <div data-bind="with: myViewModel.invoice().APInvoiceHeader">
  <asp:TextBox ID="A7txtInvoiceAmount" runat="server" Style="text-align: right" 
    data-bind="numericValue: $data.InvoiceAmount">0</asp:TextBox></div>
 </td>
 <td align="right">
  Sales Tax:
 </td>
 <td align="left" style="padding-right: 10px;">
 <div data-bind="with: myViewModel.invoice().APInvoiceHeader">
 <asp:TextBox ID="AtxtSalesTax" runat="server" Style="text-align: right"
  data-bind="value: $data.Tax">0</asp:TextBox></div>
 </td>
 </tr>
 <button  data-bind="click: myViewModel.GetXmlFromModel">lastest Model </button>
 <asp:TextBox ID="txtxml" runat="server" Visible="false"></asp:TextBox>

后面的模板控制代码(C#):

namespace Flexi.Entity.UI.SharePoint.EInvoice
{
    public class EInvoiceFieldControl : NoteField
    {
      protected EInvoiceMVCUserControl EInvoiceControl;

    protected override string DefaultTemplateName
    {
        get
        {
            return "EInvoiceFieldControl";
        }
    }
    public override string DisplayTemplateName
    {
        get
        {
            return DefaultTemplateName;
        }
        set
        {
        }
    }
    protected override void CreateChildControls()
    {
        if (this.Field != null)
        {
            base.CreateChildControls();
        //Here i get my user control initialized
            this.EInvoiceControl =  
            (EInvoiceMVCUserControl)TemplateContainer.FindControl("EInvoice");
        }
        if (this.ControlMode != SPControlMode.Display)
        {
            if (!this.Page.IsPostBack)
            {
                if (this.ControlMode == SPControlMode.New)
                {
    //I go into Model and get InitializeEntity. Works fine         

 ScriptManager.  RegisterStartupScript(this, this.GetType(), "initialize",              
 "MyMasterviewModel.myViewModel.initializemodel();", true);             
                    }
                }
                else
                {
            //ToDo later            

                }

            }
        }
        else 
        {
            //ToDo later
        }
    }
    public override object Value
    {
        get
        {
            EnsureChildControls();

    EInvoiceControl.getxml(); //This call is the one isn't working!
    return EInvoiceControl.getstringvalue();
        }
        set
        {
            EnsureChildControls();  
            base.Value = (String)value;
            }
        }
    }
 }

用户控制:

namespace Flexi.Entity.UI.SharePoint.EInvoice
{
public partial class EInvoiceMVCUserControl : UserControl
{

public void getxml()
{
 //Here is where I want to go into myViewModel.GetXmlFromModel() 
ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "lastest1", 
"MyMasterviewModel.myViewModel.GetXmlFromModel();", true);

}

   public string getstringvalue()
   {
    string val = txtxml.Text;  //It's empty here because GetXmlFromModel wasn't executed
    return val;
     }
     }
     }

我尝试直接从控件模板内部调用 registerstartupscripts,而不是去用户控件,这也不起作用。我也使用了 registerclientscripts 但没有运气。任何帮助将非常感激!!

4

2 回答 2

0

您可以订阅将在表单中更新的值:

myViewModel.myFormValue.subscribe(function(newValue){
   if(newValue){
      myViewModel.GetXmlFromModel();
   }
});

http://knockoutjs.com/documentation/observables.html

于 2013-05-08T00:05:37.053 回答
0

我最终通过使用一个可用于共享点的 Javascript 函数来解决我的问题,称为 Presaveaction(); 一旦你点击了共享点保存按钮,这个函数就会被调用。在那里我能够刷新我的模型并在屏幕上获取所有数据,

于 2013-06-11T18:09:48.310 回答