对象的范围应该是不可见的,但它看起来会如何发生?

时间:2017-08-28 02:56:22

标签: javascript knockout.js data-binding

这是将我们的视图模型显示到表中的部分的HTML代码,

帐户是帐户数组: 每个帐户都有:

1 - Id 2-姓名 3-平衡 4-存款

还有一个名为计数的计算函数可计算帐户数组中的帐号数

帐户和计数在同一范围内,即ViewModel对象

 <table class="accounts-table">
    <thead>
        <tr>
            <td>Index   </td>
            <td>Id      </td>
            <td>Accounts</td>
            <td>Balance </td>
            <td>Deposits</td>
            <td>Counts</td>
        </tr>
    </thead>
    <tbody data-bind="foreach: {data:Accounts, as: 'Account'}">
        <tr>
            <td class="accounts-table" data-bind="text:($index() + 1) + '/' + Count()" ></td>
            <td class="accounts-table" data-bind="text:Id"></td>
            <td class="accounts-table" data-bind="text:Name"></td>
            <td class="accounts-table" data-bind="text:Balance"></td>
            <td class="accounts-table">
                <ul data-bind="foreach: {data: Deposits, as: 'Amount'}">
                    <li data-bind="text:Account.Name + ' Deposits ' + Amount"></li>
                </ul>
            </td>
        </tr>
    </tbody>

这是Javascript部分:

 <script>
    function Account(id, name, balance, deposits) {
        this.Id = id;
        this.Name = name;
        this.Balance = balance;
        this.Deposits = deposits;
    }

    var myAccountViewModel = function () {
        this.Accounts = ko.observableArray([
            new Account(1, "A1", 1000, [100, 200, 300]),
            new Account(2, "A2", 2000, [400, 200, 900]),
            new Account(3, "A3", 3000, [600, 200, 800]),
            new Account(4, "A4", 4000, [700, 450, 300]),

        ]);
        this.Count = ko.computed(function () {
            return this.Accounts().length;
        },this);
    }

    ko.applyBindings(myAccountViewModel);
</script>

在这一行:

 <td class="accounts-table" data-bind="text:($index() + 1) + '/' + Count()" ></td>

当我调用Count函数时,它会如何发生? 计数功能如何在帐户范围内运作?!

1 个答案:

答案 0 :(得分:0)

在应用绑定时,您不会实例化new视图模型。

这意味着myAccountViewModelwindow的上下文中运行,并将Count属性添加到window

&#13;
&#13;
function SomeConstructor() {
  console.log("this is window", this === window);
  this.someProp = "x";
};

// Call without `new`, and `this` refers to `window`
SomeConstructor();

// `someProp` is now in `window`:
console.log("window.someProp", window.someProp);

// Call it with `new` and everything's fine!
new SomeConstructor();
&#13;
&#13;
&#13;

因为淘汰赛使用with,最终数据绑定将访问window以解决任何未定义的属性。

&#13;
&#13;
window.someProp = "x";

var someBindingContext = {
  anotherProp: "y"
};

with (someBindingContext) {
  console.log(anotherProp); // Logs y
  console.log(someProp); // Logs x, even though `someProp` is in `window`
}
&#13;
&#13;
&#13;

将您的应用绑定行更改为ko.applyBindings(new myAccountViewModel())至&#34;修复&#34;它。现在,你的内部装订需要$parent.Count()

&#13;
&#13;
function Account(id, name, balance, deposits) {
  this.Id = id;
  this.Name = name;
  this.Balance = balance;
  this.Deposits = deposits;
}

var myAccountViewModel = function() {
  this.Accounts = ko.observableArray([
    new Account(1, "A1", 1000, [100, 200, 300]),
    new Account(2, "A2", 2000, [400, 200, 900]),
    new Account(3, "A3", 3000, [600, 200, 800]),
    new Account(4, "A4", 4000, [700, 450, 300]),

  ]);
  this.Count = ko.computed(function() {
    return this.Accounts().length;
  }, this);
}

ko.applyBindings(new myAccountViewModel());
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<table class="accounts-table">
  <thead>
    <tr>
      <td>Index </td>
      <td>Id </td>
      <td>Accounts</td>
      <td>Balance </td>
      <td>Deposits</td>
      <td>Counts</td>
    </tr>
  </thead>
  <tbody data-bind="foreach: {data:Accounts, as: 'Account'}">
    <tr>
      <td class="accounts-table" data-bind="text:($index() + 1) + '/' + $parent.Count()"></td>
      <td class="accounts-table" data-bind="text:Id"></td>
      <td class="accounts-table" data-bind="text:Name"></td>
      <td class="accounts-table" data-bind="text:Balance"></td>
      <td class="accounts-table">
        <ul data-bind="foreach: {data: Deposits, as: 'Amount'}">
          <li data-bind="text:Account.Name + ' Deposits ' + Amount"></li>
        </ul>
      </td>
    </tr>
  </tbody>
&#13;
&#13;
&#13;