从C#调用KnokcoutJS ViewModel多次没有按钮点击

时间:2013-04-12 15:28:24

标签: c# javascript jquery asp.net knockout.js

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

以下是我的代码片段:

的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,而不是去找不起作用的usercontrol。我也使用了registerclientscripts,但没有运气。任何帮助都会非常感激!!

2 个答案:

答案 0 :(得分:0)

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

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

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

答案 1 :(得分:0)

我通过使用名为Presaveaction()的sharepoint的Javascript函数结束解决我的问题;只要您点击sharepoint保存按钮,就会调用此功能。在那里,我能够刷新我的模型,并在屏幕上获取所有数据,