Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Knockout.js js-如何在两个数组之间交叉引用对象_Knockout.js - Fatal编程技术网

Knockout.js js-如何在两个数组之间交叉引用对象

Knockout.js js-如何在两个数组之间交叉引用对象,knockout.js,Knockout.js,我有两种型号: var ProductModel = function(productid, productname, producttypeid, productprice) { var self = this; self.ProductId = productid; self.ProductName = productname; self.ProductTypeId = producttypeid; self.ProductPrice = productprice; }

我有两种型号:

var ProductModel = function(productid, productname, producttypeid, productprice) {
  var self = this;
  self.ProductId = productid; 
  self.ProductName = productname;
  self.ProductTypeId = producttypeid;
  self.ProductPrice = productprice;
}

我在viewmodel中使用它们:

var ProductViewModel = function() {
  var self = this;
  self.ProductList = ko.observableArray([]);
  self.ProductTypeList = ko.observableArray([]);

  //...init 2 array and some misc methods
}
在html文件中:

。。。
身份证件
类型
名称
价格
...
...
我希望我的表显示ProductTypeName而不是ProductTypeId,但我无法将ProductTypeId传递到任何函数中以获取ProductTypeName

var ProductViewModel = function() {
  var self = this;
  self.ProductList = ko.observableArray([]);
  self.ProductTypeList = ko.observableArray([]);

  //...init 2 array and some misc methods

  self.getProductTypeName = function (productTypeId) {
    var typeId = ko.unwrap(productTypeId),
        found = ko.utils.arrayFirst(self.ProductTypeList(), function (productType) {
           return ko.unwrap(productType.ProductTypeId) === typeId;
         });

    return found ? ko.unwrap(found.ProductTypeName) : null;
  };
};


您有两个相互关联的独立集合。您可以创建一个模型,该模型可以通过映射组合对象的计算观察值来管理该关联

function ProductListModel (products, productTypes) {
    this.Products = ko.observableArray(
        ko.utils.arrayMap(products, function (product) {
            return new ProductModel(
                product.productId,
                product.productName,
                product.productTypeId,
                product.productPrice);
        })
    );
    this.ProductTypes = ko.observableArray(
        ko.utils.arrayMap(productTypes, function (productType) {
            return new ProductTypeModel(
                productType.productTypeId,
                productType.productTypeName);
        })
    );

    this.AssociatedProducts = ko.dependentObservable(function () {
        var products = this.Products(),
            productTypes = this.ProductTypes();
        return ko.utils.arrayMap(products, function (product) {
            var productType = ko.utils.arrayFirst(productTypes, function (productType) {
                return product.ProductTypeId === productType.ProductTypeId;
            });
            return {
                ProductId: product.ProductId,
                ProductName: product.ProductName,
                ProductType: productType.ProductTypeName,
                ProductPrice: product.ProductPrice,
            };
        });
    }, this);
}

...

您的问题不清楚有3种类型,没有任何模型或控制器:)您应该定义类型,并在其他类型中使用它们,步骤完成后,您可以使用foreach作为类型在html中调用它们instances@HamitY我想很清楚。我可以绑定viewmodel并正确使用它。
ProductViewModel
可能有点类似于您提到的控制器。唯一困扰我的是,ProductList中的每个项都将调用此函数,并且会多次遍历ProductTypeList。我更愿意将ProductTypeList映射到类似于
{typeId:typeName,typeId:typeName…}
的东西中,以便更快地访问。为此,我将在我的主模型上使用一个计算机。getProductTypeName将使用新的computed.Yes,但只有在这成为页面的性能瓶颈之后。其他一切都是过早的优化。你就在这里。只是我的习惯,因为我们的项目后端总是发送相当多的数据。这些都是在前端处理的。在任何情况下都值得记住。这是当页面感觉迟钝时我会看到的一个点。谢谢@Tomalak,我意识到我的犯规是因为我没有打开可观察的物体。我可以为相同的结果重写您的代码:
$root.getProductTypeName(ProductTypeId())
并且在
getProductTypeName
函数中,我可以以任何方式使用参数
ProductTypeId
。您的解决方案很好!现在,您可以使用
ko.computed
而不是
ko.dependenttobservable
。但我注意到当你的应用程序使用ajax加载数据时是不安全的。在这种情况下,必须先加载
ProductTypes
,然后再加载
Products
。我知道computed和dependenttobservable之间的别名,我更喜欢后者。通常,先加载哪些值并不重要。虽然这个特定的实现将取决于它们的加载顺序,但这很容易修复。
function ProductListModel (products, productTypes) {
    this.Products = ko.observableArray(
        ko.utils.arrayMap(products, function (product) {
            return new ProductModel(
                product.productId,
                product.productName,
                product.productTypeId,
                product.productPrice);
        })
    );
    this.ProductTypes = ko.observableArray(
        ko.utils.arrayMap(productTypes, function (productType) {
            return new ProductTypeModel(
                productType.productTypeId,
                productType.productTypeName);
        })
    );

    this.AssociatedProducts = ko.dependentObservable(function () {
        var products = this.Products(),
            productTypes = this.ProductTypes();
        return ko.utils.arrayMap(products, function (product) {
            var productType = ko.utils.arrayFirst(productTypes, function (productType) {
                return product.ProductTypeId === productType.ProductTypeId;
            });
            return {
                ProductId: product.ProductId,
                ProductName: product.ProductName,
                ProductType: productType.ProductTypeName,
                ProductPrice: product.ProductPrice,
            };
        });
    }, this);
}
function ViewModel(data) {
    var p = new ProductListModel(data.products, data.productTypes);
    this.Products = p.Products;
    this.ProductTypes = p.ProductTypes;
    this.AssociatedProducts = p.AssociatedProducts;
}
<tbody data-bind="template: { name: 'row', foreach: AssociatedProducts }">
</tbody>
...
<script id="row" type="html/template">
    <tr>
        <td data-bind="html: ProductId"></td>
        <td data-bind="html: ProductName"></td>
        <td data-bind="html: ProductType"></td>
        <td data-bind="html: ProductPrice"></td>
    </tr>
</script>