模型视图Presenter设计中的Javascript“this”问题

时间:2013-04-16 10:35:49

标签: javascript this mvp

问题出在模型中,当演示者召回时它不像我想象的那样有效,事实上它就好像这个关键字指的是[ object HTMLTextAreaElement],而不是Model对象。

/** 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>

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

3 个答案:

答案 0 :(得分:0)

这一行:var public = {尽量不要使用public,即reserved word

答案 1 :(得分:0)

当您将函数作为侦听器传递时,函数内的this属性将不可用:

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

单击正文时,函数的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

答案 2 :(得分:0)

总的来说,尝试将此绑定到变量,因为这会更改当前的上下文。

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