В компании, где я работаю, мы используем jquery, и большая часть кода представляет собой очень спагетти-случайный код. Итак, чтобы лучше организовать это, я исследую реализацию подмодели pub, описанной в этом статья

Итак, я сделал действительно базовую версию вот так:

var topics = {};

jQuery.Topic = function( id ) {
    var callbacks, method,
        topic = id && topics[ id ];

    if ( !topic ) {
        callbacks = jQuery.Callbacks();
        topic = {
            publish: callbacks.fire,
            subscribe: callbacks.add,
            unsubscribe: callbacks.remove
        };
        if ( id ) {
            topics[ id ] = topic;
        }
    }
    return topic;
};

$(function() {
    var testService = new TestService();
    testService.subscribe();

    var testView = new TestView(testService);
    testView.initEvents();

});

/* ---------------------VIEW----------------- */
var TestView = function(testService) {
    this.testService = testService;
};

TestView.prototype.initEvents = function () {
    this.publishers();
};


TestView.prototype.publishers = function() {

    $("#search").on("click", function () {
        var isValid = this.testService.validateForm("#container");
        if(isValid){
            $.Topic( "search" ).publish();
        }

    })

};
/* ---------------------SERVICE----------------- */

var TestService = function() {
    this.testIdea = [];

};

TestService.prototype.validateForm = function (section) {
    var referralValid = true;
    $(section).find('input,select').filter('[required]:visible').each(function (i, requiredField) {
        if(requiredField.value === '') {
            //'breaks' the loop out
            referralValid = false;
            return referralValid;
        }
    });
    return referralValid;
};

TestService.prototype.search = function() {


};

TestService.prototype.subscribe = function() {
    var self = this;

    $.Topic("search").subscribe( function() {
        self.search()
    });

};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div>
  <div id="container">
    <input type="text">
  </div>
  <button id="search">Search</button>
</div>

Однако, когда я помещаю это в jsfiddle, я получаю сообщение об ошибке, что Uncaught TypeError: TestService не является конструктором

В фрагменте stackoverflow и в моей локальной версии я получаю другую ошибку Uncaught TypeError: Cannot read property 'validateForm' of undefined. Я не понимаю, что делаю не так. Есть указатели?

-1
Chad Watkins 5 Окт 2018 в 20:55

1 ответ

Лучший ответ

Вы можете объявлять функции конструктора так, как вы это делаете (присваивая конструктор переменной):

var TestView = function(testService) {
    this.testService = testService;
};

Как в этом простом примере:

var myClass = function(name) {
  this.name = name;
}

myClass.prototype = {
  hello: function() {
    console.log('Hello ' + this.name);
  }
}

var me = new myClass('Andrew');
me.hello();

Но вы должны не забыть объявить их, прежде чем они будут использованы. Если вы используете оператор функции (https: // developer. mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function), как было предложено Чадом Уоткинсом, это помогает только из-за подъема (http://adripofjavascript.com/blog/drips/variable-and-function-hoisting.html) не из-за функции заявление является обязательным для конструкторов.

Ошибка в вашем коде находится в строке:

$("#search").on("click", function () {
        var isValid = this.testService.validateForm("#container");

Вы ссылаетесь на объект jQuery внутри обратного вызова, а не на экземпляр TestView , вы, вероятно, хотели что-то вроде этого (каламбур не предназначен):

...
var self = this;
$("#search").on("click", function () {
        var isValid = self.testService.validateForm("#container");
...
2
agsigma 5 Окт 2018 в 19:06