Difference between knockout View Models declared as object literals vs functions

Difference between knockout View Models declared as object literals vs functions

Asked on November 14, 2018 in knockout js.
Add Comment


  • 2 Answer(s)

       There are 2 advantages in using a function to define your view model.

    main advantage : Immediate access to a value of this that is same the instance being created. This means

    var ViewModel = function(first, last)
    {
      this.first = ko.observable(first);
      this.last = ko.observable(last);
      this.full = ko.computed(function()
    {
        return this.first() + " " + this.last();
      }, this);
    };
    

       Therefore,the computed observable can be bound to the appropriate value of this, even if called from a different scope.

    With an object literal,one things to do:

    var viewModel =
    {
      first: ko.observable("Bob"),
      last: ko.observable("Smith"),
    };
    viewModel.full = ko.computed(function()
    {
      return this.first() + " " + this.last();
    }, viewModel);
    

       In that case, use viewModel directly in the computed observable, but it does get evaluated immediate (by default) so you could not define it within the object literal, as viewModel is not defined until after the object literal closed. Most people don’t like that the creation of your view model is not encapsulated into one call.

       Another pattern to use to ensure that this is always appropriate is to set a variable in the function equal to the appropriate value of this and use it instead. This would be like:

    var ViewModel = function()
    {
      var self = this;
      this.items = ko.observableArray();
      this.removeItem = function(item)
    {
        self.items.remove(item);
      }
    };
    

       Now,Stand in the scope of an individual item and call $root.removeItem, the value of this will actually be the data being bound at that level . By using self in this case, Make  sure that it is being removed from the overall view model.

       Another option is using bind, which is supported by modern browsers and added by KO, if it is not supported. In that case, it would look like:

    var ViewModel = function()
    {
      this.items = ko.observableArray();
      this.removeItem = function(item)
    {
        this.items.remove(item);
      }.bind(this);
    };
    

       There is much more that could be said on this topic and many patterns that you could explore (like module pattern and revealing module pattern), but basically using a function gives you more flexibility and control over how the object gets created and the ability to reference variables that are private to the instance.

    Answered on November 14, 2018.
    Add Comment

      Try this method:

    var viewModel = (function ()
    {
      var obj = {};
      obj.myVariable = ko.observable();
      obj.myComputed = ko.computed(function () { return "hello" + obj.myVariable() });
      ko.applyBindings(obj);
      return obj;
    })();
    

      There are 2 reasons:

        1.Not using this, which can confusion during used within ko.computeds etc

        2.The viewModel is a singleton, I don’t need to create multiple instances (i.e. new viewModel())

    Answered on November 14, 2018.
    Add Comment


  • Your Answer

    By posting your answer, you agree to the privacy policy and terms of service.