2012-12-10 11 views
8

Mój model widoku zaczął być bardzo duży, więc postanowiłem podzielić go na wiele plików. Próbowałem już wielu różnych podejść, ale nic nie działało.Podział modelu widoku z nokautu na wiele plików

Moim zdaniem modelka wygląda następująco:

namespace.model = function(constructorParam) { 
    var self = this; 

    self.param1 = ko.observable(constructorParam.param1); 
    self.param2 = ko.observable(privateFunction(constructorParam)); 

    self.clickEvent = function() { 
     // do something with params 
     // call some private funcitons 
     privateFunction2(self.param2); 
    }; 

    function privateFunction(param) { 
     // do some stuff 
    } 

    function privateFunction2(param) { 
     // do some stuff 
    } 
}; 

muszę dostęp do prywatnych funkcji i parametrów do zaobserwowania na wielu plikach. Mój ostateczny model powinien wyglądać tak:

// file 1 
// contains constructor and param initialization + many common private helper funcitons 
namespace.model = function(constructorParam) { 
    var self = this; 

    self.param1 = ko.observable(constructorParam.param1); 
    self.param2 = ko.observable(privateFunction(constructorParam)); 

    function privateFunction(param) { 
     // do some stuff 
    } 

    function privateFunction2(param) { 
     // do some stuff 
    } 
}; 

// file 2 
// contains event hendlers 
self.clickEvent = function() { 
    // i need to acces properties from namespace.model 
    self.param1 

    // call some private funcitons 
    privateFunction2(self.param2); 
}; 

// view model initialization 
ko.applyBindings(new namespace.model(initValues)); 

Czy można osiągnąć coś takiego z nokautem? Dzięki

Odpowiedz

5

chciałbym przyjrzeć biblioteki jak RequireJS które mogłyby być użyte do podzielić ViewModel do różnych „modułów”, które są następnie ładowane do głównej ViewModel.

Istnieje kilka bardzo prostych przykładów użycia RequireJS z Knockout na stronie Knockout here.

Rzuć okiem na naprawdę pomocne posty Johna Papy na temat tworzenia aplikacji z jedną stroną: here.

+2

Czy można to zrobić bez RequireJS? –

+0

@MajoB, tak, można to zrobić bez RequireJS. Jedną z korzyści wynikających z używania biblioteki takiej jak RequireJS jest to, że powoduje ona wyraźne zależności, co może być bardzo przydatne, jeśli komponujesz model z części opisanych tutaj. – kiprainey

5

Wreszcie znalazłem sposób, jak to zrobić here. Powyżej znajduje się pełna przykład:

<div> 
    Name: <input data-bind="value: name" type="text" /> <br /> 
    Surname: <input data-bind="value: surname" type="text" /><br /> 
    Fullname: <span data-bind="text: fullName"></span><br /> 
    <button data-bind="click: showName">Show Name</button> 
</div> 

<script> 

    Function.prototype.computed = function() { 
     this.isComputed = true; 
     return this; 
    }; 

    Object.prototype.makeComputeds = function() { 
     for (var prop in this) { 
      if (this[prop] && this[prop].isComputed) { 
       this[prop] = ko.computed(this[prop], this, { deferEvaluation: true }); 
      } 
     } 
    }; 
    // file 1 
    var namespace = namespace || {}; 

    namespace.model = function (params) 
    { 
     var self = this; 

     self.name = ko.observable(params.name); 
     self.surname = ko.observable(params.surname); 

     self.makeComputeds(); 
    }; 

    // file 2 
    (function() { 
     function showFullName(fullName) { 
      alert(fullName); 
     } 

     ko.utils.extend(namespace.model.prototype, { 

      showName: function() { 
       showFullName(this.fullName()); 
      }, 
      // computed observable 
      fullName: function() { 
       return this.name() + " " + this.surname(); 
      }.computed() 

     }); 

    })(); 

    ko.applyBindings(new namespace.model({ name: "My Name", surname: "My Surname" })); 

</script> 

EDIT

Jest projekt o nazwie Durandal który łączy RequireJS i KnockoutJS. Warto sprawdzić, czy jesteś zainteresowany najlepszymi praktykami architektury SPA dla KnockoutJS.

Powiązane problemy