2013-12-09 2 views
3

KnockoutJS 뷰 모델에서 일부 조작을 수행 할 수있는 함수를 어떻게 만들 수 있습니까?knockoutjs를 사용하여 뷰 모델 조작

모델 :

public class ViewModel 
{ 
    public int User { get; set; } 
    public string Address { get; set; } 
    public string ZipCode { get; set; } 
    public List<Product> Products { get; set; } 

} 

public class Product 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
} 

자바 스크립트 : 여기에이 같은 일을 추가

<script type="text/javascript"> 
     var Product = function (Id, Name) { 
      self = this; 
      self.Id = Id; 
      self.Name = Name; 
     } 

     function Add() { 
      viewModel.products.push(new Product(2, "bread")); 
     } 

     function Remove(product) { 
      viewModel.products.remove(product); 
     } 

     var viewModel = ko.mapping.fromJS(@Html.Raw(Json.Encode(Model))); 
     viewModel.products = ko.observableArray(); 

     ko.applyBindings(viewModel); 

     Add(); 
     console.log(viewModel.products().length); 

     var t = new Product(2, "bread"); 

     Remove(t); 
     console.log(viewModel.products().length); 
</script> 

하지만 function Remove(product)array에서 제품을 제거하지 않습니다. 오류가 발생하지 않고 console은 단지 1을 인쇄합니다 (viewModel.products().length 호출 모두).

KnockoutJS가 페이지의 어느 곳에서나 호출 할 수 있도록 적절한 기능을 만들려면 어떻게해야합니까?

답변

3

코드에서 명백한 것이 보이지 않습니다. 모델에서 반환되는 객체가 아니며 삭제가 실제로 작동하지만 나머지 객체는 모델에서 반환 된 것과 같습니다.

나는 그들이 다시 모델에서 읽을 때 익명 객체가 다음과 같이 생성되는 피하기 위해 개체를 매핑하는 것을 선호 :

var mapping = { 
    'Products': { 
     create: function(options) { 
      return new Product(options.data.Id, options.data.Name); 
     } 
    } 
} 

이 제품은 실제 제품 객체 보장합니다. 여기

{ "User": "a", "Address": "b", "ZipCode": "zip", "Products":[{"Id":1,"Name":"jam"}]}; 

가 jsFiddle에서 근무하는 전체 코드입니다 (출력을위한 콘솔을 확인) :

http://jsfiddle.net/6qsjz/15/ 당신은 또한 JSON이 모델에서 반환 된 것을 확인할 수 있습니다

이 같은 것입니다

모델에서 반환 된 모델 하나가 컬렉션에있는 하나의 제품을 추가하고 삭제 된 모델 하나를 보여줍니다.

당신이 당신의 모델을 변경하여 수집 서버 측을 초기화 할 수

업데이트 : 이것은 위의 접근 방식을 취할 경우 viewModel.products = ko.observableArray();을 할 필요가 없음을 의미합니다

public class ViewModel 
{ 
    public ViewModel() 
    { 
     Products = new List<Product>(); 
    } 
    public int User { get; set; } 
    public string Address { get; set; } 
    public string ZipCode { get; set; } 
    public List<Product> Products { get; set; } 

} 

.

는 업데이트

당신은 다음 (자세한 모듈) 그것은 더 나은 구조를 제공하기 위해 그것을 리팩토링 수 :

http://jsfiddle.net/6qsjz/16/ :

var Product = function (Id, Name) { 
     self = this; 
     self.Id = Id; 
     self.Name = Name; 
    } 

    var mapping = { 
     'Products': { 
      create: function(options) { 
       return new Product(options.data.Id, options.data.Name); 
      } 
     } 
    } 


function ProductsViewModel(data) { 
    var self = this; 
    ko.mapping.fromJS(data, mapping, self); 

    self.Add = function Add(product) { 
     self.Products.push(product); 
    } 

    self.Remove = function Remove(product) { 
     self.Products.remove(product); 
    } 
} 


var data = { "User": "a", "Address": "b", "ZipCode": "zip", "Products":[{"Id":1,"Name":"jam"}]}; 

    var viewModel = new ProductsViewModel(data); 
    ko.applyBindings(viewModel); 

    // add 
    var product = new Product(2, "bread"); 
    viewModel.Add(product); 
    console.log(viewModel.Products()); 

    // remove 
    viewModel.Remove(product); 
    console.log(viewModel.Products()); 

업데이트 바이올린 (다시 출력을위한 콘솔을 표시)

+0

안녕하세요,'viewModel.products = ko.observableArray();를 사용하지 않으면'var mapping = .... '을 사용할 때'pushModel'의 메소드가 아니라는 오류가 발생합니다. '. 또한, 제품은'viewModel.Products'에서 정의되지 않습니다. – Quoter

+0

안녕하세요, 작동하는 바이올린을 보셨나요? 매핑 라이브러리를 포함하고 있습니까? http://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.js – hutchonoid

+0

나는 또한 내가 사용하고있는 녹아웃 버전을 확인할 것입니다. . 당신은 바이올린 코드를 가지고 그대로 사용할 수 있습니다. 어떻게 지내는지 알려줘. – hutchonoid

2
var t = new Product(2, "bread"); 

이것은 완전히 새로운 객체를 만듭니다.t 이후

Remove(t); 

은 물체를 통과있어 경우 observableArrayremove 방법 오브젝트 ID를 사용하므로이 (동일한 부재와 완전히 다른 객체 인 경우에도) 존재하고 따라서 아무것도 제거 않겠다 아니라, 완전히 새로운 . 함수가 true 인 모든 항목을 제거하는 데 원인이 Removeremove 방법에 함수를 통과 이후

function Remove(product) { 
     viewModel.products.remove(function(item) { 
      return item.Id==product.Id; 
     }); 
    } 

당신은 다시 쓸 수있다.

var Product = function (Id, Name) { 
     self = this; 

self 여기에 글로벌이며, 다소 까다로운 이유 window 별칭은 실제로 :

이 또한 Product 생성자의 문제입니다. 접두사는 var입니다.

+0

자세한 설명을 주셔서 감사합니다! +1 – Quoter