Javascript“this"模型视图演示器设计中的问题

Javascript "this" issue in Model View Presenter design

本文关键字:问题 视图 this quot 模型 Javascript      更新时间:2023-09-26

问题是在模型,当被演示者召回时,它不像我想象的那样工作,实际上它的工作原理就像这个关键字指的是一个[object HTMLTextAreaElement],而不是一个模型对象。

/** PRESENTER **/
function Presenter() {
  var toolbarView;
  var outputView;
  var sourceCodeModel;
  var public = {
    setToolbarView: function (view) {
      toolbarView = view;
    },
    setOutputView: function (view) {
      outputView = view;
    },
    setModel: function (_model) {
      sourceCodeModel = _model;
    },
    init: function () {
      toolbarView.setNewTableHandler(function () {
        outputView.updateSource(sourceCodeModel.string);
      });
      toolbarView.setNewConstraintHandler(function () {
        /*stub*/
        alert("new constraint");
      });
    }
  }
  return public;
}
/** TOOLBAR VIEW **/
function toolbarView() {
  this.setNewTableHandler = function (handler) {
    $("#newTable").click(handler);
  }
  this.setNewConstraintHandler = function (handler) {
    $("#newConstraint").click(handler);
  }
}
/** OUTPUT VIEW **/
var outputView = {
  updateSource: function (newVal) {
    $("#sourcetext").val(newVal);
  },
  draw: function () {
    //stub
  }
};
/** MODEL **/
var model = new Object(); //o {};
model.source = [];
model.string = function () {
  /* ALERT(this) returns [object HTMLTextAreaElement] wtf? */
  var stringa = "";
  for (var i = 0; i < this.source.length; i++) { //this does not work, since this = HTMLTextAreaElement
    stringa += this.source[i] + "'n";
  }
  return stringa;
}
$(document).ready(function () {
  var presenter = new Presenter();
  var view1 = new toolbarView();
  presenter.setToolbarView(view1);
  presenter.setOutputView(outputView);
  presenter.setModel(model);
  presenter.init();
});

和HTML非常简单:

<!doctype html>
<head>
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
  <script type="text/javascript" src="mvp.js"></script>
  <meta charset="UTF-8">
  <title>Titolo documento</title>
  <style type="text/css">
    /*unnecessary here*/
  </style>
</head>
<body>
  <div id="container">
    <div id="toolbar">
      <button id="newTable">New table</button>
      <button id="newConstraint">New Constraint</button>
    </div>
    <div id="source">
      <textarea id="sourcetext"></textarea>
    </div>
    <button id="update">Update</button>
    <div id="output"></div>
  </div>
</body>
</html>

我在模型对象上做错了什么?

当你传递一个函数作为监听器时,this属性将在函数内部不可用:

var obj = {
    a: function() {
        alert(this)
    }
};
$('body').click(obj.a);

点击body,函数的this属性将变为document.body

要防止这种情况,必须绑定函数:

$('body').click(obj.a.bind(obj));

或者在旧浏览器中换行:

$('body').click(function() {
    obj.a();
});

所以你必须在传递函数之前绑定它:

outputView.updateSource(sourceCodeModel.string.bind(sourceCodeModel));

关于javascript函数上下文的更多信息:http://www.quirksmode.org/js/this.html

这一行:var public = {尽量不要使用public,那是保留字

一般注意,尝试将其绑定到一个变量,因为这会改变当前所在的上下文。

/** TOOLBAR VIEW **/
function toolbarView() {
  var that = this; 
  that.setNewTableHandler = function (handler) {
    $("#newTable").click(handler);
  }
  that.setNewConstraintHandler = function (handler) {
    $("#newConstraint").click(handler);
  }
}