2014-02-09 2 views
3

Я пытаюсь отобразить список продуктов из базы данных с помощью signalr и knockout.js. Но без какого-либо результата. Может ли кто-нибудь сказать мне, что я делаю неправильно или где у меня ошибка? Я буду очень благодарен за помощь. Это мнение:SignalR and Knockout viewmodel binding

<div class="products"> 
    <div class="row" data-bind="template: { name: 'productTemplate', foreach: products }"> 
    </div> 
    <span class="messageClass" style="color: red;"></span> 
</div> 

<script type="text/html" id="productTemplate"> 
    <div class="col-sm-6 col-md-4"> 
     <div class="thumbnail"> 
      <div class="caption"> 
       <h3 data-bind="text: name"></h3> 
      </div> 
     </div> 
    </div> 
</script> 

Это сценарий:

<script> 
     $(function() { 
      function productViewModel(id, name) { 
       this.productId = id; 
       this.name = ko.observable(name); 
       var self = this; 
      } 

      function productListViewModel() { 
       this.hub = $.connection.voteHub; 
       this.products = ko.observableArray([]); 

       var products = this.products; 

       this.init = function() { 
        this.hub.server.getAllProducts(); 
       } 

       this.hub.client.getAllProducts = function (allProducts) { 
        var mappedProducts = $.map(allProducts, function (item) { 
         return new productViewModel(item.productId, item.name) 
        }); 

        products(mappedProducts); 
       } 
      } 

      var vm = new productListViewModel(); 
      ko.applyBindings(vm); 

      $.connection.hub.start(function() { 
       vm.init(); 
      }); 
     }); 
    </script> 

Вот метод хаб, чтобы получить все продукты:

public void GetAllProducts() 
{ 
    VoteViewModel viewModel = new VoteViewModel(); 
    viewModel.Products = ProductService.GetProducts(new GetProductsRequest()).Products.ToList(); 

    if (viewModel.Products != null) 
    { 
     // TODO: pomyslec nad wysylaniem listy a nie tablicy! 
     Clients.All.getAllProducts(viewModel.Products.ToArray()); 
    } 
} 

Если я ставлю на узловом код как это будет хорошо работать (взято из демонстрационного приложения):

VoteViewModel vm = new VoteViewModel(); 
vm.Products = new List<Product>() { new Product() { Name = "Sample", Id = 1 } }; 
Clients.All.getAllProducts(vm.Products.ToArray()); 

Мой код, который выглядит так, не работает. (Я не знаю, почему, может быть, потому что мой объект продукта из БД, имеет больше переменных):

VoteViewModel viewModel = new VoteViewModel(); 
viewModel.Products = ProductService.GetProducts(new GetProductsRequest()).Products.ToList(); 
Clients.All.getAllProducts(viewModel.Products.ToArray()); 

Вот код из моего класса продукта: (DbContext класс)

[Key] 
public int Id { get; set; } 

[Required] 
public string Name { get; set; } 

public string Description { get; set; } 

[Required] 
public string ImagePath { get; set; } 

public virtual ICollection<Vote> Votes { get; set; } 

Я сделал новый класс ProductViewModel, который выглядит следующим образом:

public class ProductViewModel 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public string Description { get; set; } 
    public string ImagePath { get; set; } 
    public int VotesAmount { get; set; } 
} 

а затем связать все данные из БД в этой модели, а затем вернуть список и он работает сейчас !, но я действительно не понимаю, почему я не могу просто взять список продуктов ucts из базы данных и отправить его стороне клиента signalr (например, я пытался это сделать раньше).

List<ProductViewModel> prods = new List<ProductViewModel>(); 
    List<Product> products = ProductService.GetProducts(new GetProductsRequest()).Products.ToList(); 
    foreach (var item in products) 
    { 
     ProductViewModel prod = new ProductViewModel() 
     { 
      Id = item.Id, 
      Name = item.Name, 
      Description = item.Description, 
      ImagePath = item.ImagePath, 
      VotesAmount = item.Votes.Count() 
     }; 
     prods.Add(prod); 
    } 

    Clients.All.getAllProducts(prods.ToArray()); 

ответ

3

Ваш код абсолютно работоспособен. Проверьте, есть ли у вас ссылка на следующие файлы.

<script src="~/scripts/jquery.signalr-2.0.2.js" type="text/javascript"></script> 
<script src="~/signalr/hubs"></script> 

Signalr.hubs - это основная ссылка, которая дает файлы прокси-сервера javascripts. Если вы столкнулись с любыми ошибками, пожалуйста, дайте мне знать.

Следующая вещь - это имя свойства, указанное в создании объекта модели.

  this.hub.client.getAllProducts = function (allProducts) { 
       var mappedProducts = $.map(allProducts, function (item) { 
        return new productViewModel(item.productId, item.name) 
       }); 

       products(mappedProducts); 
      } 

Я обновил имена свойств на паскале и работал для меня.

return new productViewModel(item.ProductId, item.Name) 
+0

Под моим javascript У меня есть все необходимые ссылки, подобные тем, которые вы написали. Я исправил эти имена взамен нового productViewModel для случая pascal, как вы советуете, но даже сейчас, когда код отладки i'am добирается до метода hub, он возвращает arrayList с 2-мя продуктами, но ничто не отображается в представлении. Я попытался отладить javascript, но он никогда не попадает в this.h.client.getAllProducts для отображения продуктов. Тем не менее, я не понимаю, что происходит :(Пожалуйста, помогите – tzm

+2

Я загрузил свою демо здесь https://github.com/MisterFantastic/KnockoutSignalr, пожалуйста, проверьте код с вашим. – Thanigainathan

+0

Я отредактировал мой пост выше. Я начал менять пакеты, layout.cshtml, index и когда он начинает работать, я пытался пошагово изменить каждый шаг назад к моему коду. Он сбой при изменении кода в hub-методе. Я написал все выше – tzm