【问题标题】:Scope of the object should be not visible but its appear how that could happen?对象的范围应该是不可见的,但它看起来怎么会发生?
【发布时间】:2017-08-28 02:56:22
【问题描述】:

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

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

1 - 标识 2- 名称 3- 平衡 4- 存款

还有一个名为 Count 的计算函数,用于计算帐户数组中有多少个帐户

Accounts 和 Count 在 ViewModel 对象的同一 Scope 中

 <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 函数时,它是如何工作的? 帐户范围内的计数功能如何工作?!

【问题讨论】:

    标签: javascript knockout.js data-binding


    【解决方案1】:

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

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

    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();

    因为敲除在底层使用了with,最终,data-binds 将访问window 来解析任何未定义的属性。

    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`
    }

    将您的应用绑定行更改为ko.applyBindings(new myAccountViewModel()) 以“修复”它。现在,您的内部绑定中需要$parent.Count()

    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());
    <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>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-30
      • 2018-05-14
      • 1970-01-01
      相关资源
      最近更新 更多