2013-09-27 173 views
15

loại phức tạp của tôi sẽ không vượt qua khỏi Hiện phương pháp Init ngay cả với cấu hình MvxJsonNavigationSerializer như quy định ở đây Custom types in Navigation parameters in v3Đi qua các thông số chuyển hướng phức tạp với MvvmCross ShowViewModel

public class A 
{ 
public string String1 {get;set;} 
public string String2 {get;set;} 
public B ComplexObject1 {get;set;} 
} 

public class B 
{ 
public double Double1 {get;set;} 
public double Double2 {get;set;} 
} 

Khi tôi vượt qua thể hiện của đối tượng A đến phương pháp ShowViewModel Tôi nhận này đối tượng với String1 & String2 deserialized một cách chính xác nhưng CopmlexObject1 là null.

Làm thế nào để đối phó với đối tượng phức tạp MvvmCross serialization?

+0

tôi đã có thể giải quyết vấn đề này bằng cách thêm Plugin json mvvmcross trong dự án UIView của tôi. –

Trả lời

25

tôi tin rằng có thể có một số Gremlins trong đó câu trả lời trước - sẽ đăng nhập như một vấn đề:/


Có các tuyến đường khác có thể để đạt được kiểu này phức tạp hướng đối tượng serializable vẫn còn sử dụng Json và các bộ phận trọng của khung công tác, nhưng thực sự tôi nghĩ rằng có thể tốt hơn nếu chỉ sử dụng BaseViewModel của riêng bạn để thực hiện tuần tự hóa và deserialization - ví dụ sử dụng mã serialization như:

public class BaseViewModel 
    : MvxViewModel 
{ 
    private const string ParameterName = "parameter"; 

    protected void ShowViewModel<TViewModel>(object parameter) 
     where TViewModel : IMvxViewModel 
    { 
     var text = Mvx.Resolve<IMvxJsonConverter>().SerializeObject(parameter); 
     base.ShowViewModel<TViewModel>(new Dictionary<string, string>() 
      { 
       {ParameterName, text} 
      }); 
    } 
} 

với deserialization như:

public abstract class BaseViewModel<TInit> 
    : MvxViewModel 
{ 
    public void Init(string parameter) 
    { 
     var deserialized = Mvx.Resolve<IMvxJsonConverter>().DeserializeObject<TInit>(parameter); 
     RealInit(deserialized); 
    } 

    protected abstract void RealInit(TInit parameter); 
} 

sau đó một ViewModel như thế này:

public class FirstViewModel 
    : BaseViewModel 
{ 
    public IMvxCommand Go 
    { 
     get 
     { 
      return new MvxCommand(() => 
       { 
        var parameter = new A() 
         { 
          String1 = "Hello", 
          String2 = "World", 
          ComplexObject = new B() 
           { 
            Double1 = 42.0, 
            Double2 = -1 
           } 
         }; 
        ShowViewModel<SecondViewModel>(parameter); 
       }); 
     } 
    } 
} 

thể điều hướng đến một cái gì đó như:

public class SecondViewModel 
    : BaseViewModel<A> 
{ 
    public A A { get; set; } 

    protected override void RealInit(A parameter) 
    { 
     A = parameter; 
    } 
} 
+0

đã đăng nhập là https://github.com/slodge/MvvmCross/issues/450 – Stuart

+0

Cảm ơn bạn! Cách tiếp cận thú vị và điều đó chắc chắn sẽ hoạt động bởi vì tôi hoàn toàn kiểm soát quá trình tuần tự hóa/deserialization của bản thân mình. –

8

Một bổ sung nhỏ cho Stua câu trả lời rt để thêm an toàn kiểu:

public class BaseViewModel: MvxViewModel { 

    protected bool ShowViewModel<TViewModel, TInit>(TInit parameter) where TViewModel: BaseViewModel<TInit> { 
     var text = Mvx.Resolve<IMvxJsonConverter>().SerializeObject(parameter); 
     return base.ShowViewModel<TViewModel>(new Dictionary<string, string> { {"parameter", text} }); 
    } 
} 

public abstract class BaseViewModel<TInit> : BaseViewModel { 

    public void Init(string parameter) 
    { 
     var deserialized = Mvx.Resolve<IMvxJsonConverter>().DeserializeObject<TInit>(parameter); 
     RealInit(deserialized); 
    } 

    protected abstract void RealInit(TInit parameter); 
} 

ShowViewModel phương pháp bây giờ có một tham số kiểu tương tự mà các phương pháp RealInit thay vì một object loại. Ngoài ra, BaseViewModel<TInit> được kế thừa từ BaseViewModel để các phiên bản của chúng cũng có thể gọi phương thức ShowViewModel mới.

Hạn chế duy nhất là bạn phải xác định rõ kiểu dữ liệu tham số trong cuộc gọi như thế này:

ShowViewModel<StoreInfoViewModel, Store>(store);