使用Breeze.js在嵌套的foreach中绑定时出现意外结果

时间:2013-06-07 14:43:55

标签: knockout.js breeze

我正在使用Knockout.js 2.2.1和Breeze 1.3.5来检索和显示一些数据,但结果却没有了。数据来自自引用表。据我所知,Knockout似乎认为每个项目的 Children 属性应返回整个数组,而不是item的实际子项。我做错了什么?

更新1 :我创建了一个fiddle并获得了预期的结果,但它没有使用breeze.js。那么也许这是一个微风问题?小提琴中的一些注意事项是 Children Name 都被引用而没有括号,而在我的完整应用程序中,breeze.js似乎将它们转换为正确的observables *和要求名称的括号。

目前的结果:

Apparel
- Apparel
Art
- Art
Books
- Books
Movies
- Movies
test
- test
Blu-ray
- Blu-ray
DVD
- DVD
Animation
- Animation
Accessories
- Accessories

预期结果:

Apparel
- Accessories
Art
- Animation
Books
Movies
- Blu-ray
- DVD
test

VM:

var vm = {
    categories: ko.observableArray()
};

Knockout.js标记:

<div data-bind="foreach: categories">
    <div data-bind="text: Name"></div>
    <div data-bind="foreach: Children">
        <div data-bind="text: ' - ' + Name()"></div>
    </div>
</div>

微风代码:

var query = breeze.EntityQuery.from("Category")
    .orderBy("ParentCategoryId, Name")
    .expand("Children");

_entityManager
    .executeQuery(query)
    .then(function (data) {
        vm.categories.removeAll();
        console.log("here: " + data.results.length); -- produces 9
        data.results.forEach(function (item) {
            vm.categories.push(item);
        });
    })
    .fail(function (error) { console.log("Error: " + error); });

微风查询结果:

[ { "$id" : "1",
    "$type" : "SR.Data.Models.Domain.Category, SR.Data",
    "CategoryId" : 5,
    "Children" : [ { "$id" : "2",
          "$type" : "SR.Data.Models.Domain.Category, SR.Data",
          "CategoryId" : 6,
          "Children" : [  ],
          "CreatedOn" : "2013-05-31T11:29:11.860",
          "Description" : "Accessories",
          "IsDeleted" : false,
          "IsPublished" : true,
          "Name" : "Accessories",
          "ParentCategory" : { "$ref" : "1" },
          "ParentCategoryId" : 5
        } ],
    "CreatedOn" : "2013-05-31T11:28:37.677",
    "Description" : "Apperal",
    "IsDeleted" : false,
    "IsPublished" : true,
    "Name" : "Apparel"
  },
  { "$id" : "3",
    "$type" : "SR.Data.Models.Domain.Category, SR.Data",
    "CategoryId" : 3,
    "Children" : [ { "$id" : "4",
          "$type" : "SR.Data.Models.Domain.Category, SR.Data",
          "CategoryId" : 4,
          "Children" : [  ],
          "CreatedOn" : "2013-05-31T11:25:46.333",
          "Description" : "Animation",
          "IsDeleted" : false,
          "IsPublished" : true,
          "Name" : "Animation",
          "ParentCategory" : { "$ref" : "3" },
          "ParentCategoryId" : 3
        } ],
    "CreatedOn" : "2013-05-31T11:25:30.250",
    "Description" : "Art",
    "IsDeleted" : false,
    "IsPublished" : true,
    "Name" : "Art"
  },
  { "$id" : "5",
    "$type" : "SR.Data.Models.Domain.Category, SR.Data",
    "CategoryId" : 1,
    "Children" : [  ],
    "CreatedOn" : "2013-05-13T17:14:15.880",
    "Description" : "Books",
    "IsDeleted" : false,
    "IsPublished" : true,
    "Name" : "Books"
  },
  { "$id" : "6",
    "$type" : "SR.Data.Models.Domain.Category, SR.Data",
    "CategoryId" : 2,
    "Children" : [ { "$id" : "7",
          "$type" : "SR.Data.Models.Domain.Category, SR.Data",
          "CategoryId" : 7,
          "Children" : [  ],
          "CreatedOn" : "2013-05-31T11:31:05.710",
          "Description" : "Blu-ray",
          "IsDeleted" : false,
          "IsPublished" : true,
          "Name" : "Blu-ray",
          "ParentCategory" : { "$ref" : "6" },
          "ParentCategoryId" : 2
        },
        { "$id" : "8",
          "$type" : "SR.Data.Models.Domain.Category, SR.Data",
          "CategoryId" : 8,
          "Children" : [  ],
          "CreatedOn" : "2013-05-31T11:31:15.000",
          "Description" : "DVD",
          "IsDeleted" : false,
          "IsPublished" : true,
          "Name" : "DVD",
          "ParentCategory" : { "$ref" : "6" },
          "ParentCategoryId" : 2
        }
      ],
    "CreatedOn" : "2013-05-14T12:13:36.570",
    "Description" : "DVD's & Blu-ray",
    "IsDeleted" : false,
    "IsPublished" : true,
    "Name" : "Movies"
  },
  { "$id" : "9",
    "$type" : "SR.Data.Models.Domain.Category, SR.Data",
    "CategoryId" : 11,
    "Children" : [  ],
    "CreatedOn" : "2013-06-03T15:32:50.023",
    "Description" : "test",
    "IsDeleted" : false,
    "IsPublished" : true,
    "Name" : "test"
  },
  { "$ref" : "7" },
  { "$ref" : "8" },
  { "$ref" : "4" },
  { "$ref" : "2" }
]

类别实体:

public class Category
{
    public Category() { }

    public virtual int CategoryId { get; set; }

    public virtual int? ParentCategoryId { get; set; }

    public virtual int? PictureId { get; set; }

    public virtual string Name { get; set; }

    public virtual string Description { get; set; }

    public virtual bool IsPublished { get; set; }

    public virtual bool IsDeleted { get; set; }

    public virtual DateTime CreatedOn { get; set; }

    public virtual Category ParentCategory { get; set; }

    public virtual Picture Picture { get; set; }

    public virtual ICollection<Category> Children { get; set; }
}

类别映射:

modelBuilder.Entity<Category>().HasKey(a => a.CategoryId);
modelBuilder.Entity<Category>().HasOptional(x => x.Picture).WithMany().HasForeignKey(x => x.PictureId);
modelBuilder.Entity<Category>().HasOptional(x => x.ParentCategory).WithMany().HasForeignKey(x => x.ParentCategoryId);
modelBuilder.Entity<Category>().HasMany(x => x.Children).WithOptional().HasForeignKey(x => x.ParentCategoryId);

分类表:

Category table

2 个答案:

答案 0 :(得分:0)

分不清楚。看起来基本正确.. 除了标记错误(下面)。 JSON很不错,但在查询完成后我无法确定您对Category实体的实际情况。

在我们采取下一步之前,修复标记会发生什么?

标记错误

您不希望子模板中的“名称”后面有括号。它应该是

<div data-bind="text: ' - ' + Name"></div> <!-- NO PARENS AFTER NAME -->

就像你的小提琴一样。

清洁成功回调

当你在这里时,你可能会考虑这种替代语法,它只是用查询结果数组替换内部数组;不需要迭代。

.then(function (data) {
        vm.categories(data.results);
        console.log("here: " + data.results.length); -- produces 9
        });
    })

答案 1 :(得分:0)

终于搞清楚了!我的实体映射设置是错误的。就在我认为我不能再讨厌制造这种错综复杂的api的人时,他们证明我错了。

modelBuilder.Entity<Category>().HasOptional(x => x.ParentCategory).WithMany(x => x.ChildrenElements).HasForeignKey(x => x.ParentCategoryId);