将现有模型传递给淘汰组件绑定?

时间:2016-09-14 10:23:28

标签: javascript knockout.js knockout-3.0

我刚刚开始探索淘汰组件,因为我们的代码库在引入组件之前已经开始了。

我在第一时间读到的一些东西。

  1. 如何在component绑定时使用现有的视图模型?
  2. 调用applyBindings时应该绑定什么?
  3. 这是我的意思的一个简单例子。

    function Customer() {
      this.name = ko.observable();
      ...
      this.orders = ko.observableArray([]);
    }
    Customer.prototype.addOrder = function(order) {
      this.orders.push(order);
    }
    ...
    function Order() {
      this.date = ko.observable();
      ...
    }
    ...
    // HERE I want the component binding in the foreach to use the $data
    ko.components.register("Customer", {
      viewModel: Customer,
      template: "<strong data-bind='text: name'></strong><ul data-bind='foreach: orders'><li data-bind='component: "Order"'></li></ul>"
    });
    
    ko.components.register("Order", {
      viewModel: Order,
      template: "<span data-bind='text: date'></span>"
    });
    ...
    
    <!-- HERE I would like the component binding to use $data too -->
    <div data-bind="component: 'Customer'"></div> 
    
    ...
    
    var customer  = new Customer(); 
    customer.name = "Test";
    
    var order = new Order();
    order.data = new Date();
    customer.addOrder(order);
    
    ko.applyBindings(customer);
    

4 个答案:

答案 0 :(得分:2)

您可以通过参数(参数)将现有模型传递给组件:

function Customer(params) {
  this.name = ko.observable(params.name);
  this.orders = ko.observableArray(params.orders);
}
Customer.prototype.addOrder = function(order) {
  this.orders.push(order);
}
function Order(params) {
  this.date = ko.observable(params.date);
}

ko.components.register("customer", {
  viewModel: Customer,
  template: "<strong data-bind='text: name'></strong><ul data-bind='foreach: orders'><li><order params='date: date'></order></li></ul>"
});

ko.components.register("order", {
  viewModel: Order,
  template: "<span data-bind='text: date'></span>"
});

ko.applyBindings({ modelName: "Some Name", orders: [ { date: "01/01/01" } ] });
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

<customer params="name: modelName, orders: orders"></customer>

更新:viewModel-less组件秒杀(我喜欢@ZoltánTamási的想法):

function Customer() {
  this.name = ko.observable();
  this.orders = ko.observableArray([]);
}
Customer.prototype.addOrder = function(order) {
  this.orders.push(order);
}
function Order() {
  this.date = ko.observable();
}
ko.components.register("customer", {
  viewModel: function(params) { return params.model; },
  template: "<strong data-bind='text: name'></strong><ul data-bind='foreach: orders'><li><order params='model: $data'></order></li></ul>"
});

ko.components.register("order", {
  viewModel: function(params) { return params.model; },
  template: "<span data-bind='text: date'></span>"
});

var customer  = new Customer(); 
customer.name = "Test";

var order = new Order();
order.date = new Date(Date.now());
customer.addOrder(order);

ko.applyBindings({ customer: customer });
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

<customer params="model: customer"></customer> 

答案 1 :(得分:1)

您正在寻找的解决方案是使用此视图模型工厂注册您的组件:

ko.components.register("your-element", { 
    template: {...}, 
   { createViewModel: (params, componentInfo) => ko.dataFor(componentInfo.element) };
};

这会让你&#34;通过&#34;绑定,例如:

<div data-bind="with: SomeModel">
    <your-element></your-element>
</div>

为模板加载的HTML中的视图模型将是SomeModel。

答案 2 :(得分:0)

最后一个问题:您仍然applyBindings到应用程序的viewmodel。使用组件不会改变它。

组件can receive parameters。这就是你将任何东西传递给他们的viewmodel构造函数的方法。

答案 3 :(得分:0)

您是否尝试过使用&#34; 共享对象实例&#34;像这里:http://knockoutjs.com/documentation/component-registration.html#specifying-a-viewmodel