【问题标题】:Passing parameter from Knockout template to modal将参数从 Knockout 模板传递到模态
【发布时间】:2015-12-21 14:15:18
【问题描述】:

在这个代码示例中,我正在寻找一种将参数从 Knockout 的 template 中的 data 传递到 Knockout 的 data-bind 的方法,该参数最终应该出现在 modal 窗口中。

结果应该是一个模式窗口,根据要删除的参与者显示参与者的姓名。

现在我必须手动输入名称,应该怎么做才能让它们自动绑定?

var viewModel = function() {
  this.showModal = function() {
    console.log("Showing modal");
    $('#modal').modal('show');
  }
  this.buyer = {
    name: 'Franklin',
    credits: 250
  };
  this.seller = {
    name: 'Mario',
    credits: 5800
  };
};
ko.applyBindings(new viewModel);
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap-theme.min.css" rel="stylesheet" />
<link href="https://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

<div data-bind="template: { name: 'person-template', data: buyer }"></div>
<div data-bind="template: { name: 'person-template', data: seller }"></div>

<script type="text/html" id="person-template">
  <h3 data-bind="text: name"></h3>
  <p>Credits: <span data-bind="text: credits"></span>
  </p>
  <button data-bind="click: $root.showModal" class="btn">Delete</button>
</script>

<div id="modal" class="modal fade" tabindex="-1" role="dialog">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span>
        </button>
        <h4 class="modal-title">Delete item</h4>
      </div>
      <div class="modal-body">
        <p>Really delete Franklin?</p>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
        <button type="button" class="btn btn-primary">Delete</button>
      </div>
    </div>
    <!-- /.modal-content -->
  </div>
  <!-- /.modal-dialog -->
</div>
<!-- /.modal -->

【问题讨论】:

    标签: javascript knockout.js knockout-2.0 knockout-3.0 knockout-templating


    【解决方案1】:

    首先,您需要让名称由 KO 管理:

    <p>Really delete <span data-bind="text: deleting"></span>?</p>
    

    在你的视图模型中给自己一个 observable:

    this.deleting = ko.observable(null);
    

    然后更新showModal 来更新一个observable:

    this.showModal = function(deleting) {
      this.deleting(deleting.name);
      console.log("Showing modal");
      $('#modal').modal('show');
    };
    

    那么,由于您使用的是$root.showModal,this 将是不正确的,但我们可以使用bind 来解决这个问题:

    <button data-bind="click: $root.showModal.bind($root)" class="btn">Delete</button>
    

    实例:

    var viewModel = function() {
      this.showModal = function(deleting) {
        this.deleting(deleting.name);
        console.log("Showing modal");
        $('#modal').modal('show');
      };
      this.deleting = ko.observable(null);
      this.buyer = {
        name: 'Franklin',
        credits: 250
      };
      this.seller = {
        name: 'Mario',
        credits: 5800
      };
    };
    ko.applyBindings(new viewModel);
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap-theme.min.css" rel="stylesheet" />
    <link href="https://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet" />
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
    <div data-bind="template: { name: 'person-template', data: buyer }"></div>
    <div data-bind="template: { name: 'person-template', data: seller }"></div>
    
    <script type="text/html" id="person-template">
      <h3 data-bind="text: name"></h3>
      <p>Credits: <span data-bind="text: credits"></span>
      </p>
      <button data-bind="click: $root.showModal.bind($root)" class="btn">Delete</button>
    </script>
    
    <div id="modal" class="modal fade" tabindex="-1" role="dialog">
      <div class="modal-dialog">
        <div class="modal-content">
          <div class="modal-header">
            <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span>
            </button>
            <h4 class="modal-title">Delete item</h4>
          </div>
          <div class="modal-body">
            <p>Really delete <span data-bind="text: deleting"></span>?</p>
          </div>
          <div class="modal-footer">
            <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
            <button type="button" class="btn btn-primary">Delete</button>
          </div>
        </div>
        <!-- /.modal-content -->
      </div>
      <!-- /.modal-dialog -->
    </div>
    <!-- /.modal -->

    【讨论】:

    • click 绑定自动绑定到$data。你不必这样做。除此之外,我的答案只是你的重复。如果你更新你的,我会删除我的。
    • @RoyJ:是的,我们需要bind,原因是我给出的:因为他们使用的是$root.showModal。如果他们只是使用showModal,它就会有正确的this。我们可以使用bind 来避免使用self 的伎俩。
    • @T.J.Crowder 有什么好的理由来避免“自我欺骗”吗? (另外,为什么它首先是一个“技巧”?)
    • 好的,重点。当我使用 bind() 而不是将 this 固定到局部变量时,引擎究竟可以优化什么? (这里真的很感兴趣。我还以为关闭了。)
    • @Tomalak:V8 确实做到了这一点,我希望 SpiderMonkey 和其他人也能做到这一点,在一些非常狭窄的范围内。 V8 从堆栈上的bar 之类的东西开始,然后只在需要时创建一个真正的词法环境(因为返回的函数引用bar)。 也就是说,除非出现真正的问题,否则它是一个微型选择。 :-) 而且我还没有研究箭头函数(关闭 this)对它的影响,尽管我怀疑有一天会得到优化(一旦 ES6 支持完成并且他们有时间回去调整)。
    【解决方案2】:

    您需要在视图模型中有一个变量来指示选择了哪一个。然后在click 绑定中,根据传递(自动!)到点击绑定的数据来设置它。

    var viewModel = function() {
      var self = this;
      this.showModal = function(data) {
        console.log("Showing modal", data);
        self.selected(data.name);
        $('#modal').modal('show');
      }
      this.selected = ko.observable();
      this.buyer = {
        name: 'Franklin',
        credits: 250
      };
      this.seller = {
        name: 'Mario',
        credits: 5800
      };
    };
    ko.applyBindings(new viewModel);
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap-theme.min.css" rel="stylesheet" />
    <link href="https://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet" />
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
    <div data-bind="template: { name: 'person-template', data: buyer }"></div>
    <div data-bind="template: { name: 'person-template', data: seller }"></div>
    
    <script type="text/html" id="person-template">
      <h3 data-bind="text: name"></h3>
      <p>Credits: <span data-bind="text: credits"></span>
      </p>
      <button data-bind="click: $root.showModal" class="btn">Delete</button>
    </script>
    
    <div id="modal" class="modal fade" tabindex="-1" role="dialog">
      <div class="modal-dialog">
        <div class="modal-content">
          <div class="modal-header">
            <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span>
            </button>
            <h4 class="modal-title">Delete item</h4>
          </div>
          <div class="modal-body">
            <p>Really delete <span data-bind="text:selected"></span>?</p>
          </div>
          <div class="modal-footer">
            <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
            <button type="button" class="btn btn-primary">Delete</button>
          </div>
        </div>
        <!-- /.modal-content -->
      </div>
      <!-- /.modal-dialog -->
    </div>
    <!-- /.modal -->

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-24
      • 1970-01-01
      • 1970-01-01
      • 2018-03-11
      • 2021-02-08
      • 2015-08-05
      相关资源
      最近更新 更多