创建没有淘汰代码的淘汰视图模型

时间:2015-10-01 15:31:09

标签: knockout.js knockout-3.0

创建一个没有任何淘汰代码的淘汰视图模型是否有意义?这意味着没有观察者,订阅者或任何淘汰赛功能吗?

我有一些应用程序的常用功能,例如模态,闪光警报,通知,日期选择...

我通常使用主视图模型通过其他视图模型访问它们:

var MasterModel = function(){
    this.comments = new commentsViewModel().init();
    this.equipment = new equipmentViewModel().init();

    //fake viewmodels
    this.notification = new notificationViewModel().init();
    this.alert = new alertsViewModel().init();
};

var mm = new MasterModel();

ko.applyBindings(mm)

然后我可以在任何viewModel中使用以下内容:

mm.alert.show('Demo');

为什么我将它们保留为视图模型?它简化了事情。

  • 我可以将它们保持在与viewmodels
  • 相同的路径下
  • 我可以在将来决定使用可观察或任何淘汰功能

1 个答案:

答案 0 :(得分:0)

如果您只是想创建一种方法来减少警报或其他与ViewModel无关的代码的重复,那么您可能最好只创建一个具有这些辅助函数的“实用程序”类。 / p>

但是,如果你想减少代码,因为你的视图模型有很多共同点,那么我认为使用继承是一个更好的途径。

以下是我在我的项目中所做的简化示例:

function baseObj(args) {
  if (this instanceof baseObj === false) return new baseObj(args);
  return this.memberVars(args);
}

baseObj.prototype = function() {
  var defaults = {
    viewOnly: false
  };

  function memberVars(args) {
    var settings = $.extend({}, defaults, args);
    var id = ko.observable();
    var readOnly = ko.observable(settings.viewOnly ? true : false);

    var isCreated = ko.pureComputed({
      read: function() {
        return id() ? true : false;
      },
      deferEvaluation: true
    });

    Object.defineProperty(this, "id", {value: id,enumerable: true});
    //FYI: these are not enumerable because I don't want them to
    //end up in the JSON.
    Object.defineProperty(this, "readOnly", {value: readOnly});
    Object.defineProperty(this, "isCreated", {value: isCreated});
    return this;
  }

  function init(data) {
    console.log("base init");
    if (data) {
      this.id(data.id);
    }

    return this;
  }

  function saveObj() {
    console.log("saving " + this.constructor.name + "(" + this.id() + ")");
  };

  function deleteObj() {
    console.log("deleting " + this.constructor.name+ "(" + this.id() + ")");
  };

  Object.defineProperty(baseObj.prototype, "memberVars", {value: memberVars});
  Object.defineProperty(baseObj.prototype, "init", {value: init});
  Object.defineProperty(baseObj.prototype, "saveObj", {value: saveObj});
  Object.defineProperty(baseObj.prototype, "deleteObj", {value: deleteObj});
  return baseObj.prototype;
}();

function personObj(args) {
  if (this instanceof personObj === false) return new personObj(args);
  return this.memberVars(args);
}

personObj.prototype = function setProto(base) {
  function memberVars(settings) {
    base.memberVars.call(this, settings);

    var firstName = ko.observable("");
    var lastName = ko.observable("");

    var fullName = ko.pureComputed({
      read: function() {
        var result = "";
        var tmpFirst = firstName();
        var tmpLast = lastName();

        if (tmpFirst)
          result += tmpFirst;

        if (tmpLast)
          result += " " + tmpLast;

        return result;
      },
      deferEvaluation: true
    });

    Object.defineProperty(this, "firstName", {value: firstName,enumerable: true});
    Object.defineProperty(this, "lastName", {value: lastName});
    Object.defineProperty(this, "fullName", {value: fullName});
    return this;
  }

  function init(data) {
    base.init.call(this, data);
    if (data) {
      this.firstName(data.firstName || "");
      this.lastName(data.lastName || "");
    }
  }

  var obj = Object.create(base);
  Object.defineProperty(obj, "constructor", {value: personObj});
  Object.defineProperty(obj, "memberVars", {value: memberVars});
  Object.defineProperty(obj, "init", {value: init});
  return obj;
}(baseObj.prototype);

普兰克:http://plnkr.co/9uNu1yJSsUoTVLgnBtFZ