如果模型不是顶级对象,如何将模型绑定到模型中? [英] How to bind a model to knockout if the model is not a top-level object?

查看:56
本文介绍了如果模型不是顶级对象,如何将模型绑定到模型中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习kickout.js.我之前做了一个示例,我试图通过两种方式对其进行修改:

I am learning knockout.js. I did one example earlier, which I am trying to modify in two ways:

  1. 我组织了代码以最大程度地减小全局范围,因此在window对象中只有一个顶级对象,并将包括模型在内的所有内容都放在其中.

  1. I organized the code to minimize global scope so there's just one top-level object inside the window object and I put everything including my model in there.

如果模型不可观察,我想看看在模型更改时text:绑定是否会更改视图.有关此想法的详细说明,请参见下面的HTML代码中的注释.

I wanted to see if the text: binding changes the view when the model changes if the model is not an observable. For a finer elaboration of this idea, please see the comments in the HTML code below.

但是,当我运行这段代码时,我得到一个ReferenceError: friend is not defined.

However, when I run this bit of code, I get a ReferenceError: friend is not defined.

我认为是因为我的model对象不再是window对象的顶级成员.

I am assuming it is because of the fact that my model object is no longer a top-level member of the window object.

是否可以具有这样的模型层次结构,并使其与剔除一起工作?

Is it possible to have a model hierarchy like this and have it work with knockout?

1a.html

<html>
    <head>
        <meta charset="utf-8"/>
        <script type='text/javascript' src='knockout-3.4.0.js'></script>
    </head>

    <!-- The purpose of this program is to find out whether just a 
        text: binding also changes the display / view if the model changes.
        Meaning if I explicitly do not create an observable out of a model property
        and use only a text: binding, does the property still behave like an observable?

        To do this, I am using the same code as 1.html and 1.js, 
        except for one change. I am adding another set of textboxes
        in which I will type in a new first name and last name.
        Then, I will click the "Update Name" button
        in whose listener, I will update the model properties friend.firstName
        and friend.lastName.

        Then, I'd like to see if the text box values for txtFirstName and txtLastName
        change.
        -->
    <body>

        <form id = "frm" name = "frm">
            <fieldset>
                <legend>Your friend's basic information:</legend>

                <div>
                    <label for = "FirstName">First Name</label>
                    <input type = "text" name = "FirstName" id = "txtFirstName" data-bind = "value: friend.firstName" />
                </div>

                <div>
                    <label for = "LastName">Last Name</label>
                    <input type = "text" name = "LastName" id = "txtLastName" data-bind = "value: friend.lastName" />
                </div>


                    <fieldset>
                        <legend>New Information:</legend>

                        <div>
                            <label for = "NewFirstName">New Value for First Name</label>
                            <input type = "text" name = "NewFirstName" id = "txtNewFirstName" />
                        </div>

                        <div>
                            <label for = "NewLastName">New Value for Last Name</label>
                            <input type = "text" name = "NewLastName" id = "txtNewLastName" />
                        </div>
                    </fieldset>

                <div>
                    <input type = "button" value = "Update Name" id = "btnUpdateName" name = "Save" />
                </div>
            </fieldset>

        </form>

        <script type='text/javascript' src='1a.js'></script>
    </body>
</html>

1a.js

var ThisDocument = function()
{
    this.model = 
    {
        friend : 
        {
            firstName : 'Sathyaish',
            lastName : 'Chakravarthy'
        }
    };

    this.init = function()
    {
        wire(window, "load", wireElementHandlers);
    };

    function wire(element, eventName, listener)
    {
        var ie = document.all ? true : false;

        if (!element) throw new Error("Element " + element + " not found.");

        if (ie)
        {
            element.attachEvent("on" + eventName, listener);
        }
        else
        {
            element.addEventListener(eventName, listener, false);
        }
    };


    function wireElementHandlers()
    {
        var btnUpdateName = document.getElementById('btnUpdateName');
        wire(btnUpdateName, "click", changeName);

        ko.applyBindings(this.model);
    };

    function changeName(event)
    {
        var firstName = document.getElementById('txtNewFirstName').value;
        var lastName = document.getElementById('txtNewLastName').value;

        this.model.friend.firstName = firstName;
        this.model.friend.lastName = lastName;
    };
};

var thisDocument = new ThisDocument();
thisDocument.init();

使模型成为窗口内的顶级对象

但是,如果我使模型成为window对象中的顶级成员,则代码可以正常工作,并且我知道上面的HTML注释和项目符号#2中描述的问题的答案.以上.

If, however, I make the model a top-level member inside the window object, the code works fine and I get to know the answer to my question described in the HTML comments above and in the bullet point #2 above.

答案是:不.如果没有可观察的内容,当模型更改时,简单的text:绑定不会更新视图.

The answer is: no. Without having an observable, a simple text: binding does not update the view when the model changes.

以下是将模型作为顶层对象的代码:

Here is the code with the model as the top-level object:

1a.js

this.model = 
{
    friend : 
    {
        firstName : 'Sathyaish',
        lastName : 'Chakravarthy'
    }
};

var ThisDocument = function()
{
    this.init = function()
    {
        wire(window, "load", wireElementHandlers);
    };

    function wire(element, eventName, listener)
    {
        var ie = document.all ? true : false;

        if (!element) throw new Error("Element " + element + " not found.");

        if (ie)
        {
            element.attachEvent("on" + eventName, listener);
        }
        else
        {
            element.addEventListener(eventName, listener, false);
        }
    };


    function wireElementHandlers()
    {
        var btnUpdateName = document.getElementById('btnUpdateName');
        wire(btnUpdateName, "click", changeName);

        ko.applyBindings(model);
    };

    function changeName(event)
    {
        var firstName = document.getElementById('txtNewFirstName').value;
        var lastName = document.getElementById('txtNewLastName').value;

        model.friend.firstName = firstName;
        model.friend.lastName = lastName;
    };
};

var thisDocument = new ThisDocument();
thisDocument.init();

因此,我怀疑this指针被弄乱了.

Therefore, my suspicion is that the this pointer is being messed up.

applyBindings方法是否有重载,或者如果不是重载,则可能是另一种方式,它允许我告诉敲除绑定模型时使用特定对象作为this参数?

Is there an overload for the applyBindings method or may be another way if not an overload that allows me to tell knockout to use a particular object as the this parameter when binding a model?

例如

var MyDocument = function()
{
  var model = 
  {
    friend : { firstName: 'Sathyaish', lastName: 'Chakravarthy' }
  };

  this.init : function()
  {
    ko.applyBindings(this.model /*, but this may lead knockout
    to not be able to discover my model, as my experience so far
    shows. I need to recalibrate the 'this' pointer so knockout
    knows to look for the model object inside whatever I tell it to, 
    i.e. inside an instance of the MyDocument class and not inside
    whatever the this pointer happens to reference when knockout 
    is performing the binding. */);
  };
}

var myDocument = new MyDocument();
myDocument.init();

推荐答案

我认为您确实需要映射插件,并且要更改/输入值需要这样做:

I think you really need the mapping plugin and to change/put a value will need to do:

model.friend.firstName(firstName)

稍后我将尝试您的代码,如果有必要,我将编辑我的答案.

I will try your code later and if is necessary i will edit my answer.

这篇关于如果模型不是顶级对象,如何将模型绑定到模型中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆